blob: 6c23cdcb2b492f248c64691e193d1f5b9761e658 [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 Shiota9a1e6d12014-04-03 14:47:12 -0700194
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700195 # Filling RAMCloud parameters
196 local host_role=$(read-conf ${CLUSTER_CONF} "cluster.${host}.role")
197 if [ "${host_role}" = "coord-node" -o "${host_role}" = "coord-and-server-node" ]; then
198 sed -i -e "s|__RAMCLOUD_COORD_IP__|${rc_ip}|" ${tempfile}
199 sed -i -e "s|__RAMCLOUD_COORD_PORT__|${rc_coord_port}|" ${tempfile}
200 else
201 # comment out
202 sed -i -e "s|^\(.*__RAMCLOUD_COORD_IP__.*\)$|#\1|" ${tempfile}
203 sed -i -e "s|^\(.*__RAMCLOUD_COORD_PORT__.*\)$|#\1|" ${tempfile}
204 fi
205 if [ "${host_role}" = "server-node" -o "${host_role}" = "coord-and-server-node" ]; then
206 sed -i -e "s|__RAMCLOUD_SERVER_IP__|${rc_ip}|" ${tempfile}
207 sed -i -e "s|__RAMCLOUD_SERVER_PORT__|${rc_server_port}|" ${tempfile}
208 else
209 # comment out
210 sed -i -e "s|^\(.*__RAMCLOUD_SERVER_IP__.*\)$|#\1|" ${tempfile}
211 sed -i -e "s|^\(.*__RAMCLOUD_SERVER_PORT__.*\)$|#\1|" ${tempfile}
212 fi
213 sed -i -e "s|__RAMCLOUD_SERVER_REPLICAS__|${CLUSTER_RC_SERVER_REPLICAS}|" ${tempfile}
214
215 # Filling Hazelcast parameters
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700216 if [ ${CLUSTER_HC_NETWORK} = "tcp-ip" ]; then
217 sed -i -e "s|__HAZELCAST_MEMBERS__|${hc_hosts}|" ${tempfile}
218
219 # Comment out unused parameters
220 sed -i -e "s|^\(.*__HAZELCAST_MULTICAST_GROUP__.*\)$|#\1|" ${tempfile}
221 sed -i -e "s|^\(.*__HAZELCAST_MULTICAST_PORT__.*\)$|#\1|" ${tempfile}
222 elif [ ${CLUSTER_HC_NETWORK} = "multicast" ]; then
223 sed -i -e "s|__HAZELCAST_MULTICAST_GROUP__|${CLUSTER_HC_ADDR}|" ${tempfile}
224 sed -i -e "s|__HAZELCAST_MULTICAST_PORT__|${CLUSTER_HC_PORT}|" ${tempfile}
225
226 sed -i -e "s|^\(.*__HAZELCAST_MEMBERS__.*\)$|#\1|" ${tempfile}
227 fi
228
229 end-conf-creation ${onos_conf}
Naoki Shiotab76bc652014-04-28 19:26:13 -0700230
231 echo "DONE"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700232}
233
234# setup -f : force overwrite existing files
235function setup {
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700236 mkdir -p ${CLUSTER_CONF_OUTPUT_DIR}
237
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700238 if [ "${1}" = "-f" ]; then
239 create-pssh-conf
240
241 for host in ${CLUSTER_HOSTS}; do
242 create-onos-conf ${host}
243 done
244 else
245 create-conf-interactive ${PSSH_CONF} create-pssh-conf
246
247 for host in ${CLUSTER_HOSTS}; do
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700248 local filename="${CLUSTER_CONF_OUTPUT_DIR}/onos_node.${host}.conf"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700249 create-conf-interactive ${filename} create-onos-conf ${host}
250 done
251 fi
252}
253
254############################################
255
256
257############ Deploy functions ##############
258
259function deploy {
260 if [ ! -f ${PSSH_CONF} ]; then
261 echo "[ERROR] ${PSSH_CONF} not found"
262 local command=`basename ${0}`
263 echo "[ERROR] Try \"${command} setup\" to create files."
264 exit 1
265 fi
266
Naoki Shiota05721b32014-04-29 14:41:12 -0700267 mkdir -p ${CLUSTER_LOGDIR}
268
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700269 for host in ${CLUSTER_HOSTS}; do
Naoki Shiota611f3dd2014-05-30 11:38:37 -0700270 local conf=${CLUSTER_CONF_OUTPUT_DIR}/onos_node.${host}.conf
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700271 if [ ! -f ${conf} ]; then
272 echo "[ERROR] ${conf} not found"
273 local command=`basename ${0}`
274 echo "[ERROR] Try \"${command} setup\" to create files."
275 exit 1
276 fi
Naoki Shiota05721b32014-04-29 14:41:12 -0700277
278 local filename=`basename ${conf}`
279 echo -n "Copying ${filename} to ${host} ... "
280
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700281 local user=$(read-conf ${CLUSTER_CONF} "remote.${host}.ssh.user")
Naoki Shiotab7eb55d2014-04-21 18:21:36 -0700282 if [ -z "${user}" ]; then
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700283 # falling back to common setting
284 user=$(read-conf ${CLUSTER_CONF} "remote.common.ssh.user")
285 fi
Naoki Shiotab76bc652014-04-28 19:26:13 -0700286
Naoki Shiota05721b32014-04-29 14:41:12 -0700287 local login=
Naoki Shiotab76bc652014-04-28 19:26:13 -0700288 if [ -z "${user}" ]; then
289 user=`whoami`
290 fi
291
Naoki Shiota05721b32014-04-29 14:41:12 -0700292 ${SCP} ${conf} ${user}@${host}:${REMOTE_ONOS_CONF_DIR} &> ${CLUSTER_LOGDIR}/deploy.${host}.log
293 echo "DONE"
294
295 echo -n "Configuring ${host} ... "
296 ${SSH} ${user}@${host} "cd ${REMOTE_ONOS_HOME}; ./onos.sh setup -f; ./build-ramcloud-java-bindings.sh" &>> ${CLUSTER_LOGDIR}/deploy.${host}.log
297 echo "DONE"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700298 done
299
300# TODO: Replacing per-host ssh command with pssh command below.
301# Need to solve concurrency problem when ONOS directory is shared among hosts.
302# ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh setup -f"
303}
304############################################
305
306
307############# Start functions ##############
308
309function start {
310 if [ ! -f ${PSSH_CONF} ]; then
311 echo "[ERROR] ${PSSH_CONF} not found"
312 local command=`basename ${0}`
313 echo "[ERROR] Try \"${command} setup\" to create files."
314 exit 1
315 fi
316
Naoki Shiotab76bc652014-04-28 19:26:13 -0700317 echo "Starting ONOS cluster"
318 ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh start 2>&1"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700319}
320
321############################################
322
323
324############# Stop functions $##############
325
326function stop {
327 if [ ! -f ${PSSH_CONF} ]; then
328 echo "[ERROR] ${PSSH_CONF} not found"
329 local command=`basename ${0}`
330 echo "[ERROR] Try \"${command} setup\" to create files."
331 exit 1
332 fi
333
Naoki Shiotab76bc652014-04-28 19:26:13 -0700334 echo "Stopping ONOS cluster"
335 ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh stop 2>&1"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700336}
337
338############################################
339
340
341############ Status functions ##############
342
343function status {
344 if [ ! -f ${PSSH_CONF} ]; then
345 echo "[ERROR] ${PSSH_CONF} not found"
346 local command=`basename ${0}`
347 echo "[ERROR] Try \"${command} setup\" to create files."
348 exit 1
349 fi
350
Naoki Shiotab76bc652014-04-28 19:26:13 -0700351 ${PSSH} -i -h ${PSSH_CONF} "cd ${REMOTE_ONOS_HOME}; ./onos.sh status 2>&1"
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700352}
353
354############################################
355
356
Naoki Shiota05721b32014-04-29 14:41:12 -0700357############## Cmd functions ###############
358
359function do-cmd {
360 local cmd=$*
361
362 if [ -z "${cmd}" ]; then
363 print-usage
364 else
365 ${PSSH} -i -h ${PSSH_CONF} "${cmd}"
366 fi
367}
368
369############################################
370
371
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700372################## Main ####################
373case "$1" in
374 setup)
375 setup $2
376 ;;
377 deploy)
378 deploy
379 ;;
380 start)
381 start
382 ;;
383 stop)
384 stop
385 ;;
386 stat*) # <- status
387 status
388 ;;
Naoki Shiota05721b32014-04-29 14:41:12 -0700389 cmd)
390 array=("$@")
391 unset array[0]
392 do-cmd ${array[@]}
393 ;;
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700394 *)
Naoki Shiota05721b32014-04-29 14:41:12 -0700395 print-usage
Naoki Shiota9a1e6d12014-04-03 14:47:12 -0700396 exit 1
397esac