blob: f49c07b56e01eb4ac928e584c5c3f4a10ca87721 [file] [log] [blame]
Naoki Shiota9a1e6d12014-04-03 14:47:12 -07001#! /bin/bash
2
3set -e
4
5### Env vars used by this script. (default value) ###
Naoki Shiota05721b32014-04-29 14:41:12 -07006# $ONOS_HOME : path of root directory of ONOS repository (~/ONOS)
7# $ONOS_CLUSTER_HOME : path of ONOS cluster tools directory (this script's dir)
8# $REMOTE_ONOS_HOME : path of root directory of ONOS repository in remote hosts (ONOS)
9# $ONOS_CLUSTER_LOGDIR : path of log output directory (~/ONOS/cluster-mgmt/logs)
10# $SSH : command name to access host
11# $PSSH : command name to access hosts in parallel
12# $SCP : command name to copy config file to each host
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070013#####################################################
14
15
16### Variables read from ONOS config file ###
17ONOS_HOME=${ONOS_HOME:-${HOME}/ONOS}
18
19source ${ONOS_HOME}/scripts/common/utils.sh
20
21CLUSTER_HOME=${ONOS_CLUSTER_HOME:-$(cd `dirname $0`; pwd)}
22CLUSTER_CONF_DIR=${CLUSTER_HOME}/conf
23CLUSTER_CONF=${ONOS_CLUSTER_CONF:-${CLUSTER_CONF_DIR}/onos-cluster.conf}
Naoki Shiota611f3dd2014-05-30 11:38:37 -070024CLUSTER_CONF_OUTPUT_DIR=${CLUSTER_CONF_DIR}/generated
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070025CLUSTER_TEMPLATE_DIR=${CLUSTER_CONF_DIR}/template
Naoki Shiota05721b32014-04-29 14:41:12 -070026CLUSTER_LOGDIR=${ONOS_CLUSTER_LOGDIR:-${CLUSTER_HOME}/logs}
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070027
28REMOTE_ONOS_HOME=${REMOTE_ONOS_HOME:-ONOS}
29REMOTE_ONOS_CONF_DIR=${REMOTE_ONOS_HOME}/conf
30
31if [ ! -f ${CLUSTER_CONF} ]; then
32 echo "${CLUSTER_CONF} not found."
33 exit 1
34fi
Naoki Shiota9109a1e2014-05-13 11:11:01 -070035CLUSTER_HOSTS=$(read-conf ${CLUSTER_CONF} cluster.hosts.names `hostname` | tr ',' ' ')
36CLUSTER_BACKEND=$(read-conf ${CLUSTER_CONF} cluster.hosts.backend)
37CLUSTER_RC_PROTOCOL=$(read-conf ${CLUSTER_CONF} cluster.hosts.ramcloud.protocol "fast+udp")
38CLUSTER_RC_SERVER_REPLICAS=$(read-conf ${CLUSTER_CONF} cluster.hosts.ramcloud.server.replicas "0")
39CLUSTER_HC_NETWORK=$(read-conf ${CLUSTER_CONF} cluster.hosts.hazelcast.network)
40CLUSTER_HC_ADDR=$(read-conf ${CLUSTER_CONF} cluster.hosts.hazelcast.multicast.address "224.2.2.3")
41CLUSTER_HC_PORT=$(read-conf ${CLUSTER_CONF} cluster.hosts.hazelcast.multicast.port "54327")
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070042############################################
43
44
45ONOS_CONF_TEMPLATE=${CLUSTER_TEMPLATE_DIR}/onos_node.conf.template
46
47
48### Parallel SSH settings ###
49SSH=${SSH:-ssh}
50PSSH=${PSSH:-parallel-ssh}
Naoki Shiota611f3dd2014-05-30 11:38:37 -070051PSSH_CONF=${CLUSTER_CONF_OUTPUT_DIR}/pssh.hosts
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070052SCP=${SCP:-scp}
53#############################
54
55
56############# Common functions #############
Naoki Shiota05721b32014-04-29 14:41:12 -070057function print-usage {
58 local scriptname=`basename $0`
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070059 local usage="Usage: setup/deploy/start/stop/status ONOS cluster.
Naoki Shiota05721b32014-04-29 14:41:12 -070060 \$ ${scriptname} setup [-f]
61 Set up ONOS cluster using ${CLUSTER_CONF}.
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070062 If -f option is used, all existing files will be overwritten without confirmation.
Naoki Shiota05721b32014-04-29 14:41:12 -070063 \$ ${scriptname} deploy [-f]
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070064 Deliver node config files to cluster nodes.
65 If -f option is used, all existing files will be overwritten without confirmation.
Naoki Shiota05721b32014-04-29 14:41:12 -070066 \$ ${scriptname} start
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070067 Start ONOS cluster
Naoki Shiota05721b32014-04-29 14:41:12 -070068 \$ ${scriptname} stop
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070069 Stop ONOS cluster
Naoki Shiota05721b32014-04-29 14:41:12 -070070 \$ ${scriptname} status
71 Show status of ONOS-cluster
72 \$ ${scriptname} cmd {command to execute}
73 Execute command on all hosts in parallel"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070074
75 echo "${usage}"
76}
77
78############################################
79
80
81############# Setup functions ##############
82
83function list-zk-hosts {
84 local list=()
85 for host in ${CLUSTER_HOSTS}; do
86 local zk_host_string=$(read-conf ${CLUSTER_CONF} "cluster.${host}.zk.host")
87
Naoki Shiotab7eb55d2014-04-21 18:21:36 -070088 if [ -z "${zk_host_string}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070089 # falling back to ip
90 zk_host_string=$(read-conf ${CLUSTER_CONF} "cluster.${host}.ip")
91 fi
Naoki Shiotab7eb55d2014-04-21 18:21:36 -070092 if [ -z "${zk_host_string}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070093 # falling back to hostname
94 zk_host_string=${host}
95 fi
96
97 list=("${list[@]}" ${zk_host_string})
98 done
99
100 # join with comma
101 local IFS=,
102 echo "${list[*]}"
103}
104
105function list-hc-hosts {
106 local list=()
107 for host in ${CLUSTER_HOSTS}; do
108 local hc_host_string=$(read-conf ${CLUSTER_CONF} "cluster.${host}.hazelcast.ip")
109
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700110 if [ -z "${hc_host_string}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700111 # falling back to ip
112 hc_host_string=$(read-conf ${CLUSTER_CONF} "cluster.${host}.ip")
113 fi
114
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700115 if [ -z "${hc_host_string}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700116 # falling back to hostname
117 hc_host_string=${host}
118 fi
119
120 list=("${list[@]}" ${hc_host_string})
121 done
122
123 local IFS=,
124 echo "${list[*]}"
125}
126
127function create-pssh-conf {
128 local tempfile=`begin-conf-creation ${PSSH_CONF}`
129
Naoki Shiotab76bc652014-04-28 19:26:13 -0700130 local filename=`basename ${PSSH_CONF}`
131 echo -n "Creating ${filename} ... "
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700132 # creation of pssh config file
133 for host in ${CLUSTER_HOSTS}; do
134 local user=$(read-conf ${CLUSTER_CONF} remote.${host}.ssh.user)
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700135 if [ -z "${user}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700136 # falling back to common setting
137 user=$(read-conf ${CLUSTER_CONF} remote.common.ssh.user)
138 fi
139
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700140 if [ -z "${user}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700141 echo ${host} >> ${tempfile}
142 else
143 echo ${user}@${host} >> ${tempfile}
144 fi
145 done
146
147 end-conf-creation ${PSSH_CONF}
Naoki Shiotab76bc652014-04-28 19:26:13 -0700148 echo "DONE"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700149}
150
151# create-onos-conf {hostname}
152function create-onos-conf {
153 local host_name=${1}
154
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700155 if [ -z "${host_name}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700156 echo "FAILED"
157 echo "[ERROR] invalid hostname ${host_name}"
158 exit 1
159 fi
160
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700161 local onos_conf="${CLUSTER_CONF_OUTPUT_DIR}/onos_node.${host_name}.conf"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700162 local tempfile=`begin-conf-creation ${onos_conf}`
Naoki Shiotab76bc652014-04-28 19:26:13 -0700163 local filename=`basename ${onos_conf}`
164 echo -n "Creating ${filename} ... "
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700165
166 cp ${ONOS_CONF_TEMPLATE} ${tempfile}
167
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700168 local prefix="cluster.${host_name}"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700169
170 local host_ip=$(read-conf ${CLUSTER_CONF} "${prefix}.ip")
171 local host_string=${host_ip}
172 if [ -z "${host_string}" ]; then
173 host_string=${host_name}
174 fi
175 local host_role=$(read-conf ${CLUSTER_CONF} "${prefix}.role")
176 local zk_hosts=`list-zk-hosts`
177 local rc_ip=$(read-conf ${CLUSTER_CONF} "${prefix}.ramcloud.ip" ${host_string})
178 local rc_coord_port=$(read-conf ${CLUSTER_CONF} "${prefix}.ramcloud.coordinator.port" 12246)
179 local rc_server_port=$(read-conf ${CLUSTER_CONF} "${prefix}.ramcloud.server.port" 12242)
180 local hc_hosts=`list-hc-hosts`
181
182 # creation of ONOS node config file
183 sed -i -e "s|__HOST_NAME__|${host_name}|" ${tempfile}
184 if [ -z "${host_ip}" ]; then
185 # comment out
186 sed -i -e "s|^\(.*__HOST_IP__.*\)$|#\1|" ${tempfile}
187 else
188 sed -i -e "s|__HOST_IP__|${host_ip}|" ${tempfile}
189 fi
190 sed -i -e "s|__ONOS_ROLE__|${host_role}|" ${tempfile}
191 sed -i -e "s|__BACKEND__|${CLUSTER_BACKEND}|" ${tempfile}
192 sed -i -e "s|__ZK_HOSTS__|${zk_hosts}|" ${tempfile}
193 sed -i -e "s|__RAMCLOUD_PROTOCOL__|${CLUSTER_RC_PROTOCOL}|" ${tempfile}
Naoki Shiota801875c2014-05-29 17:06:06 -0700194 sed -i -e "s|__RAMCLOUD_IP__|${rc_ip}|" ${tempfile}
195 sed -i -e "s|__RAMCLOUD_COORD_PORT__|${rc_coord_port}|" ${tempfile}
196 sed -i -e "s|__RAMCLOUD_SERVER_PORT__|${rc_server_port}|" ${tempfile}
197 sed -i -e "s|__RAMCLOUD_SERVER_REPLICAS__|${CLUSTER_RC_SERVER_REPLICAS}|" ${tempfile}
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700198
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700199 # Filling RAMCloud parameters
200 local host_role=$(read-conf ${CLUSTER_CONF} "cluster.${host}.role")
201 if [ "${host_role}" = "coord-node" -o "${host_role}" = "coord-and-server-node" ]; then
202 sed -i -e "s|__RAMCLOUD_COORD_IP__|${rc_ip}|" ${tempfile}
203 sed -i -e "s|__RAMCLOUD_COORD_PORT__|${rc_coord_port}|" ${tempfile}
204 else
205 # comment out
206 sed -i -e "s|^\(.*__RAMCLOUD_COORD_IP__.*\)$|#\1|" ${tempfile}
207 sed -i -e "s|^\(.*__RAMCLOUD_COORD_PORT__.*\)$|#\1|" ${tempfile}
208 fi
209 if [ "${host_role}" = "server-node" -o "${host_role}" = "coord-and-server-node" ]; then
210 sed -i -e "s|__RAMCLOUD_SERVER_IP__|${rc_ip}|" ${tempfile}
211 sed -i -e "s|__RAMCLOUD_SERVER_PORT__|${rc_server_port}|" ${tempfile}
212 else
213 # comment out
214 sed -i -e "s|^\(.*__RAMCLOUD_SERVER_IP__.*\)$|#\1|" ${tempfile}
215 sed -i -e "s|^\(.*__RAMCLOUD_SERVER_PORT__.*\)$|#\1|" ${tempfile}
216 fi
217 sed -i -e "s|__RAMCLOUD_SERVER_REPLICAS__|${CLUSTER_RC_SERVER_REPLICAS}|" ${tempfile}
218
219 # Filling Hazelcast parameters
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700220 if [ ${CLUSTER_HC_NETWORK} = "tcp-ip" ]; then
221 sed -i -e "s|__HAZELCAST_MEMBERS__|${hc_hosts}|" ${tempfile}
222
223 # Comment out unused parameters
224 sed -i -e "s|^\(.*__HAZELCAST_MULTICAST_GROUP__.*\)$|#\1|" ${tempfile}
225 sed -i -e "s|^\(.*__HAZELCAST_MULTICAST_PORT__.*\)$|#\1|" ${tempfile}
226 elif [ ${CLUSTER_HC_NETWORK} = "multicast" ]; then
227 sed -i -e "s|__HAZELCAST_MULTICAST_GROUP__|${CLUSTER_HC_ADDR}|" ${tempfile}
228 sed -i -e "s|__HAZELCAST_MULTICAST_PORT__|${CLUSTER_HC_PORT}|" ${tempfile}
229
230 sed -i -e "s|^\(.*__HAZELCAST_MEMBERS__.*\)$|#\1|" ${tempfile}
231 fi
232
233 end-conf-creation ${onos_conf}
Naoki Shiotab76bc652014-04-28 19:26:13 -0700234
235 echo "DONE"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700236}
237
238# setup -f : force overwrite existing files
239function setup {
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700240 mkdir -p ${CLUSTER_CONF_OUTPUT_DIR}
241
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700242 if [ "${1}" = "-f" ]; then
243 create-pssh-conf
244
245 for host in ${CLUSTER_HOSTS}; do
246 create-onos-conf ${host}
247 done
248 else
249 create-conf-interactive ${PSSH_CONF} create-pssh-conf
250
251 for host in ${CLUSTER_HOSTS}; do
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700252 local filename="${CLUSTER_CONF_OUTPUT_DIR}/onos_node.${host}.conf"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700253 create-conf-interactive ${filename} create-onos-conf ${host}
254 done
255 fi
256}
257
258############################################
259
260
261############ Deploy functions ##############
262
263function deploy {
264 if [ ! -f ${PSSH_CONF} ]; then
265 echo "[ERROR] ${PSSH_CONF} not found"
266 local command=`basename ${0}`
267 echo "[ERROR] Try \"${command} setup\" to create files."
268 exit 1
269 fi
270
Naoki Shiota05721b32014-04-29 14:41:12 -0700271 mkdir -p ${CLUSTER_LOGDIR}
272
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700273 for host in ${CLUSTER_HOSTS}; do
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700274 local conf=${CLUSTER_CONF_OUTPUT_DIR}/onos_node.${host}.conf
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700275 if [ ! -f ${conf} ]; then
276 echo "[ERROR] ${conf} not found"
277 local command=`basename ${0}`
278 echo "[ERROR] Try \"${command} setup\" to create files."
279 exit 1
280 fi
Naoki Shiota05721b32014-04-29 14:41:12 -0700281
282 local filename=`basename ${conf}`
283 echo -n "Copying ${filename} to ${host} ... "
284
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700285 local user=$(read-conf ${CLUSTER_CONF} "remote.${host}.ssh.user")
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700286 if [ -z "${user}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700287 # falling back to common setting
288 user=$(read-conf ${CLUSTER_CONF} "remote.common.ssh.user")
289 fi
Naoki Shiotab76bc652014-04-28 19:26:13 -0700290
Naoki Shiota05721b32014-04-29 14:41:12 -0700291 local login=
Naoki Shiotab76bc652014-04-28 19:26:13 -0700292 if [ -z "${user}" ]; then
293 user=`whoami`
294 fi
295
Naoki Shiota05721b32014-04-29 14:41:12 -0700296 ${SCP} ${conf} ${user}@${host}:${REMOTE_ONOS_CONF_DIR} &> ${CLUSTER_LOGDIR}/deploy.${host}.log
297 echo "DONE"
298
299 echo -n "Configuring ${host} ... "
300 ${SSH} ${user}@${host} "cd ${REMOTE_ONOS_HOME}; ./onos.sh setup -f; ./build-ramcloud-java-bindings.sh" &>> ${CLUSTER_LOGDIR}/deploy.${host}.log
301 echo "DONE"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700302 done
303
304# TODO: Replacing per-host ssh command with pssh command below.
305# Need to solve concurrency problem when ONOS directory is shared among hosts.
306# ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh setup -f"
307}
308############################################
309
310
311############# Start functions ##############
312
313function start {
314 if [ ! -f ${PSSH_CONF} ]; then
315 echo "[ERROR] ${PSSH_CONF} not found"
316 local command=`basename ${0}`
317 echo "[ERROR] Try \"${command} setup\" to create files."
318 exit 1
319 fi
320
Naoki Shiotab76bc652014-04-28 19:26:13 -0700321 echo "Starting ONOS cluster"
322 ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh start 2>&1"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700323}
324
325############################################
326
327
328############# Stop functions $##############
329
330function stop {
331 if [ ! -f ${PSSH_CONF} ]; then
332 echo "[ERROR] ${PSSH_CONF} not found"
333 local command=`basename ${0}`
334 echo "[ERROR] Try \"${command} setup\" to create files."
335 exit 1
336 fi
337
Naoki Shiotab76bc652014-04-28 19:26:13 -0700338 echo "Stopping ONOS cluster"
339 ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh stop 2>&1"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700340}
341
342############################################
343
344
345############ Status functions ##############
346
347function status {
348 if [ ! -f ${PSSH_CONF} ]; then
349 echo "[ERROR] ${PSSH_CONF} not found"
350 local command=`basename ${0}`
351 echo "[ERROR] Try \"${command} setup\" to create files."
352 exit 1
353 fi
354
Naoki Shiotab76bc652014-04-28 19:26:13 -0700355 ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh status 2>&1"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700356}
357
358############################################
359
360
Naoki Shiota05721b32014-04-29 14:41:12 -0700361############## Cmd functions ###############
362
363function do-cmd {
364 local cmd=$*
365
366 if [ -z "${cmd}" ]; then
367 print-usage
368 else
369 ${PSSH} -i -h ${PSSH_CONF} "${cmd}"
370 fi
371}
372
373############################################
374
375
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700376################## Main ####################
377case "$1" in
378 setup)
379 setup $2
380 ;;
381 deploy)
382 deploy
383 ;;
384 start)
385 start
386 ;;
387 stop)
388 stop
389 ;;
390 stat*) # <- status
391 status
392 ;;
Naoki Shiota05721b32014-04-29 14:41:12 -0700393 cmd)
394 array=("$@")
395 unset array[0]
396 do-cmd ${array[@]}
397 ;;
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700398 *)
Naoki Shiota05721b32014-04-29 14:41:12 -0700399 print-usage
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700400 exit 1
401esac