blob: 0e03c292c7da27ee295c0d7ca29bc08b8e07f654 [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}
24CLUSTER_TEMPLATE_DIR=${CLUSTER_CONF_DIR}/template
Naoki Shiota05721b32014-04-29 14:41:12 -070025CLUSTER_LOGDIR=${ONOS_CLUSTER_LOGDIR:-${CLUSTER_HOME}/logs}
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070026
27REMOTE_ONOS_HOME=${REMOTE_ONOS_HOME:-ONOS}
28REMOTE_ONOS_CONF_DIR=${REMOTE_ONOS_HOME}/conf
29
30if [ ! -f ${CLUSTER_CONF} ]; then
31 echo "${CLUSTER_CONF} not found."
32 exit 1
33fi
34CLUSTER_HOSTS=$(read-conf ${CLUSTER_CONF} cluster.hosts.names `hostname` | tr ',' ' ')
35CLUSTER_BACKEND=$(read-conf ${CLUSTER_CONF} cluster.hosts.backend)
36CLUSTER_RC_PROTOCOL=$(read-conf ${CLUSTER_CONF} cluster.hosts.ramcloud.protocol "fast+udp")
37CLUSTER_HC_NETWORK=$(read-conf ${CLUSTER_CONF} cluster.hosts.hazelcast.network)
38CLUSTER_HC_ADDR=$(read-conf ${CLUSTER_CONF} cluster.hosts.hazelcast.multicast.address "224.2.2.3")
39CLUSTER_HC_PORT=$(read-conf ${CLUSTER_CONF} cluster.hosts.hazelcast.multicast.port "54327")
40############################################
41
42
43ONOS_CONF_TEMPLATE=${CLUSTER_TEMPLATE_DIR}/onos_node.conf.template
44
45
46### Parallel SSH settings ###
47SSH=${SSH:-ssh}
48PSSH=${PSSH:-parallel-ssh}
49PSSH_CONF=${CLUSTER_CONF_DIR}/pssh.hosts
50SCP=${SCP:-scp}
51#############################
52
53
54############# Common functions #############
Naoki Shiota05721b32014-04-29 14:41:12 -070055function print-usage {
56 local scriptname=`basename $0`
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070057 local usage="Usage: setup/deploy/start/stop/status ONOS cluster.
Naoki Shiota05721b32014-04-29 14:41:12 -070058 \$ ${scriptname} setup [-f]
59 Set up ONOS cluster using ${CLUSTER_CONF}.
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070060 If -f option is used, all existing files will be overwritten without confirmation.
Naoki Shiota05721b32014-04-29 14:41:12 -070061 \$ ${scriptname} deploy [-f]
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070062 Deliver node config files to cluster nodes.
63 If -f option is used, all existing files will be overwritten without confirmation.
Naoki Shiota05721b32014-04-29 14:41:12 -070064 \$ ${scriptname} start
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070065 Start ONOS cluster
Naoki Shiota05721b32014-04-29 14:41:12 -070066 \$ ${scriptname} stop
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070067 Stop ONOS cluster
Naoki Shiota05721b32014-04-29 14:41:12 -070068 \$ ${scriptname} status
69 Show status of ONOS-cluster
70 \$ ${scriptname} cmd {command to execute}
71 Execute command on all hosts in parallel"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070072
73 echo "${usage}"
74}
75
76############################################
77
78
79############# Setup functions ##############
80
81function list-zk-hosts {
82 local list=()
83 for host in ${CLUSTER_HOSTS}; do
84 local zk_host_string=$(read-conf ${CLUSTER_CONF} "cluster.${host}.zk.host")
85
Naoki Shiotab7eb55d2014-04-21 18:21:36 -070086 if [ -z "${zk_host_string}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070087 # falling back to ip
88 zk_host_string=$(read-conf ${CLUSTER_CONF} "cluster.${host}.ip")
89 fi
Naoki Shiotab7eb55d2014-04-21 18:21:36 -070090 if [ -z "${zk_host_string}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -070091 # falling back to hostname
92 zk_host_string=${host}
93 fi
94
95 list=("${list[@]}" ${zk_host_string})
96 done
97
98 # join with comma
99 local IFS=,
100 echo "${list[*]}"
101}
102
103function list-hc-hosts {
104 local list=()
105 for host in ${CLUSTER_HOSTS}; do
106 local hc_host_string=$(read-conf ${CLUSTER_CONF} "cluster.${host}.hazelcast.ip")
107
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700108 if [ -z "${hc_host_string}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700109 # falling back to ip
110 hc_host_string=$(read-conf ${CLUSTER_CONF} "cluster.${host}.ip")
111 fi
112
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700113 if [ -z "${hc_host_string}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700114 # falling back to hostname
115 hc_host_string=${host}
116 fi
117
118 list=("${list[@]}" ${hc_host_string})
119 done
120
121 local IFS=,
122 echo "${list[*]}"
123}
124
125function create-pssh-conf {
126 local tempfile=`begin-conf-creation ${PSSH_CONF}`
127
Naoki Shiotab76bc652014-04-28 19:26:13 -0700128 local filename=`basename ${PSSH_CONF}`
129 echo -n "Creating ${filename} ... "
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700130 # creation of pssh config file
131 for host in ${CLUSTER_HOSTS}; do
132 local user=$(read-conf ${CLUSTER_CONF} remote.${host}.ssh.user)
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700133 if [ -z "${user}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700134 # falling back to common setting
135 user=$(read-conf ${CLUSTER_CONF} remote.common.ssh.user)
136 fi
137
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700138 if [ -z "${user}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700139 echo ${host} >> ${tempfile}
140 else
141 echo ${user}@${host} >> ${tempfile}
142 fi
143 done
144
145 end-conf-creation ${PSSH_CONF}
Naoki Shiotab76bc652014-04-28 19:26:13 -0700146 echo "DONE"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700147}
148
149# create-onos-conf {hostname}
150function create-onos-conf {
151 local host_name=${1}
152
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700153 if [ -z "${host_name}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700154 echo "FAILED"
155 echo "[ERROR] invalid hostname ${host_name}"
156 exit 1
157 fi
158
159 local onos_conf="${CLUSTER_CONF_DIR}/onos_node.${host_name}.conf"
160 local tempfile=`begin-conf-creation ${onos_conf}`
Naoki Shiotab76bc652014-04-28 19:26:13 -0700161 local filename=`basename ${onos_conf}`
162 echo -n "Creating ${filename} ... "
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700163
164 cp ${ONOS_CONF_TEMPLATE} ${tempfile}
165
166 local prefix="cluster.${host}"
167
168 local host_ip=$(read-conf ${CLUSTER_CONF} "${prefix}.ip")
169 local host_string=${host_ip}
170 if [ -z "${host_string}" ]; then
171 host_string=${host_name}
172 fi
173 local host_role=$(read-conf ${CLUSTER_CONF} "${prefix}.role")
174 local zk_hosts=`list-zk-hosts`
175 local rc_ip=$(read-conf ${CLUSTER_CONF} "${prefix}.ramcloud.ip" ${host_string})
176 local rc_coord_port=$(read-conf ${CLUSTER_CONF} "${prefix}.ramcloud.coordinator.port" 12246)
177 local rc_server_port=$(read-conf ${CLUSTER_CONF} "${prefix}.ramcloud.server.port" 12242)
178 local hc_hosts=`list-hc-hosts`
179
180 # creation of ONOS node config file
181 sed -i -e "s|__HOST_NAME__|${host_name}|" ${tempfile}
182 if [ -z "${host_ip}" ]; then
183 # comment out
184 sed -i -e "s|^\(.*__HOST_IP__.*\)$|#\1|" ${tempfile}
185 else
186 sed -i -e "s|__HOST_IP__|${host_ip}|" ${tempfile}
187 fi
188 sed -i -e "s|__ONOS_ROLE__|${host_role}|" ${tempfile}
189 sed -i -e "s|__BACKEND__|${CLUSTER_BACKEND}|" ${tempfile}
190 sed -i -e "s|__ZK_HOSTS__|${zk_hosts}|" ${tempfile}
191 sed -i -e "s|__RAMCLOUD_PROTOCOL__|${CLUSTER_RC_PROTOCOL}|" ${tempfile}
192 sed -i -e "s|__RAMCLOUD_IP__|${rc_ip}|" ${tempfile}
193 sed -i -e "s|__RAMCLOUD_COORD_PORT__|${rc_coord_port}|" ${tempfile}
194 sed -i -e "s|__RAMCLOUD_SERVER_PORT__|${rc_server_port}|" ${tempfile}
195
196 if [ ${CLUSTER_HC_NETWORK} = "tcp-ip" ]; then
197 sed -i -e "s|__HAZELCAST_MEMBERS__|${hc_hosts}|" ${tempfile}
198
199 # Comment out unused parameters
200 sed -i -e "s|^\(.*__HAZELCAST_MULTICAST_GROUP__.*\)$|#\1|" ${tempfile}
201 sed -i -e "s|^\(.*__HAZELCAST_MULTICAST_PORT__.*\)$|#\1|" ${tempfile}
202 elif [ ${CLUSTER_HC_NETWORK} = "multicast" ]; then
203 sed -i -e "s|__HAZELCAST_MULTICAST_GROUP__|${CLUSTER_HC_ADDR}|" ${tempfile}
204 sed -i -e "s|__HAZELCAST_MULTICAST_PORT__|${CLUSTER_HC_PORT}|" ${tempfile}
205
206 sed -i -e "s|^\(.*__HAZELCAST_MEMBERS__.*\)$|#\1|" ${tempfile}
207 fi
208
209 end-conf-creation ${onos_conf}
Naoki Shiotab76bc652014-04-28 19:26:13 -0700210
211 echo "DONE"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700212}
213
214# setup -f : force overwrite existing files
215function setup {
216 if [ "${1}" = "-f" ]; then
217 create-pssh-conf
218
219 for host in ${CLUSTER_HOSTS}; do
220 create-onos-conf ${host}
221 done
222 else
223 create-conf-interactive ${PSSH_CONF} create-pssh-conf
224
225 for host in ${CLUSTER_HOSTS}; do
226 local filename="${CLUSTER_CONF_DIR}/onos_node.${host}.conf"
227 create-conf-interactive ${filename} create-onos-conf ${host}
228 done
229 fi
230}
231
232############################################
233
234
235############ Deploy functions ##############
236
237function deploy {
238 if [ ! -f ${PSSH_CONF} ]; then
239 echo "[ERROR] ${PSSH_CONF} not found"
240 local command=`basename ${0}`
241 echo "[ERROR] Try \"${command} setup\" to create files."
242 exit 1
243 fi
244
Naoki Shiota05721b32014-04-29 14:41:12 -0700245 mkdir -p ${CLUSTER_LOGDIR}
246
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700247 for host in ${CLUSTER_HOSTS}; do
248 local conf=${CLUSTER_CONF_DIR}/onos_node.${host}.conf
249 if [ ! -f ${conf} ]; then
250 echo "[ERROR] ${conf} not found"
251 local command=`basename ${0}`
252 echo "[ERROR] Try \"${command} setup\" to create files."
253 exit 1
254 fi
Naoki Shiota05721b32014-04-29 14:41:12 -0700255
256 local filename=`basename ${conf}`
257 echo -n "Copying ${filename} to ${host} ... "
258
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700259 local user=$(read-conf ${CLUSTER_CONF} "remote.${host}.ssh.user")
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700260 if [ -z "${user}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700261 # falling back to common setting
262 user=$(read-conf ${CLUSTER_CONF} "remote.common.ssh.user")
263 fi
Naoki Shiotab76bc652014-04-28 19:26:13 -0700264
Naoki Shiota05721b32014-04-29 14:41:12 -0700265 local login=
Naoki Shiotab76bc652014-04-28 19:26:13 -0700266 if [ -z "${user}" ]; then
267 user=`whoami`
268 fi
269
Naoki Shiota05721b32014-04-29 14:41:12 -0700270 ${SCP} ${conf} ${user}@${host}:${REMOTE_ONOS_CONF_DIR} &> ${CLUSTER_LOGDIR}/deploy.${host}.log
271 echo "DONE"
272
273 echo -n "Configuring ${host} ... "
274 ${SSH} ${user}@${host} "cd ${REMOTE_ONOS_HOME}; ./onos.sh setup -f; ./build-ramcloud-java-bindings.sh" &>> ${CLUSTER_LOGDIR}/deploy.${host}.log
275 echo "DONE"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700276 done
277
278# TODO: Replacing per-host ssh command with pssh command below.
279# Need to solve concurrency problem when ONOS directory is shared among hosts.
280# ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh setup -f"
281}
282############################################
283
284
285############# Start functions ##############
286
287function start {
288 if [ ! -f ${PSSH_CONF} ]; then
289 echo "[ERROR] ${PSSH_CONF} not found"
290 local command=`basename ${0}`
291 echo "[ERROR] Try \"${command} setup\" to create files."
292 exit 1
293 fi
294
Naoki Shiotab76bc652014-04-28 19:26:13 -0700295 echo "Starting ONOS cluster"
296 ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh start 2>&1"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700297}
298
299############################################
300
301
302############# Stop functions $##############
303
304function stop {
305 if [ ! -f ${PSSH_CONF} ]; then
306 echo "[ERROR] ${PSSH_CONF} not found"
307 local command=`basename ${0}`
308 echo "[ERROR] Try \"${command} setup\" to create files."
309 exit 1
310 fi
311
Naoki Shiotab76bc652014-04-28 19:26:13 -0700312 echo "Stopping ONOS cluster"
313 ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh stop 2>&1"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700314}
315
316############################################
317
318
319############ Status functions ##############
320
321function status {
322 if [ ! -f ${PSSH_CONF} ]; then
323 echo "[ERROR] ${PSSH_CONF} not found"
324 local command=`basename ${0}`
325 echo "[ERROR] Try \"${command} setup\" to create files."
326 exit 1
327 fi
328
Naoki Shiotab76bc652014-04-28 19:26:13 -0700329 ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh status 2>&1"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700330}
331
332############################################
333
334
Naoki Shiota05721b32014-04-29 14:41:12 -0700335############## Cmd functions ###############
336
337function do-cmd {
338 local cmd=$*
339
340 if [ -z "${cmd}" ]; then
341 print-usage
342 else
343 ${PSSH} -i -h ${PSSH_CONF} "${cmd}"
344 fi
345}
346
347############################################
348
349
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700350################## Main ####################
351case "$1" in
352 setup)
353 setup $2
354 ;;
355 deploy)
356 deploy
357 ;;
358 start)
359 start
360 ;;
361 stop)
362 stop
363 ;;
364 stat*) # <- status
365 status
366 ;;
Naoki Shiota05721b32014-04-29 14:41:12 -0700367 cmd)
368 array=("$@")
369 unset array[0]
370 do-cmd ${array[@]}
371 ;;
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700372 *)
Naoki Shiota05721b32014-04-29 14:41:12 -0700373 print-usage
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700374 exit 1
375esac