Statistics
| Branch: | Tag: | Revision:

root / tools / vcluster-setup.in @ 3695a4e0

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
LUXID_ARGS=''
207

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

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

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

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

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

    
229
setup_etc_hosts() {
230
  echo "Configuring $etc_hosts_filename ..." >&2
231
  (
232
    set -e -u
233
    local -r tmpfile=$(mktemp $etc_hosts_filename.vcluster.XXXXX)
234
    trap "rm -f $tmpfile" EXIT
235
    {
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)"
240
      done
241
      for ((i=0; i < instcount; ++i)); do
242
        echo "$(instance_ipaddr $i) $(instance_hostname $i)"
243
      done
244
    } > $tmpfile && \
245
    chmod 0644 $tmpfile && \
246
    mv $tmpfile $etc_hosts_filename && \
247
    trap - EXIT
248
  )
249
}
250

    
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"
257
  done
258
}
259

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

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

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

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

    
290
  cat <<EOF
291

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

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

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

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

    
316
exit 0
317

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