1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
#!/bin/bash
#
# Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved.
# Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v1.0 which accompanies this distribution,
# and is available at http://www.eclipse.org/legal/epl-v10.html
#
function usage()
{
# Print any error messages
test "$1" != "" && echo " ERROR: $1"
# Print standard usage help
cat << EOF
This script is used to configure cluster parameters on this
controller. The user should restart controller to apply changes.
Usage: $0 <seed_nodes_list>
- seed_nodes_list: List of seed nodes, separated by comma or space.
The script checks that one (any) of the the controller's active IP
addresses is present in the seed_nodes_list. When running this script
on multiple seed nodes, keep the seed_node_list same on all nodes.
Optionally, shards can be configured in a more granular way by
modifying the file "custom_shard_configs.txt" in the same folder
as this tool. Please see that file for more details.
This script is currently limited to IPv4 addresses. If you have
problems running this script, please use 'configure_cluster.sh'.
EOF
exit 1
}
function start_banner
{
cat <<EOF
################################################
## Configure Cluster ##
################################################
EOF
}
function end_banner
{
cat <<EOF
################################################
## NOTE: Manually restart controller to ##
## apply configuration. ##
################################################
EOF
}
# Utility function for joining strings.
function join {
delim=',\n\t\t\t\t'
final=$1; shift
for str in $* ; do
final=${final}${delim}${str}
done
echo ${final}
}
function create_strings
{
# Using a list of controller IPs, create the strings for data
# and rpc seed nodes, as well as the list of members.
# First create an arrays with one string per controller.
# Then merge the array using the join utility defined above.
count=1
for ip in ${CONTROLLERIPS[@]} ; do
ds[$count]=\\\"akka.tcp:\\/\\/opendaylight-cluster-data@${ip}:2550\\\"
rpc[$count]=\\\"akka.tcp:\\/\\/odl-cluster-rpc@${ip}:2551\\\"
members[$count]=\\\"member-${count}\\\"
count=$[count + 1]
done
DATA_SEED_LIST=$(join ${ds[@]})
RPC_SEED_LIST=$(join ${rpc[@]})
MEMBER_NAME_LIST=$(join ${members[@]})
}
function module_shards_builder
{
module_shards_string="module-shards = [\n\t{\n\t\tname = \"default\"\n\t\tshards = [\n\t\t\t{\n\t\t\t\tname = \"default\"\n\t\t\t\treplicas = []\n\t\t\t}\n\t\t]\n\t}"
for name in ${FRIENDLY_MODULE_NAMES[@]} ; do
module_shards_string="${module_shards_string},\n\t{\n\t\tname = \"${name}\"\n\t\tshards = [\n\t\t\t{\n\t\t\t\tname=\"${name}\"\n\t\t\t\treplicas = []\n\t\t\t}\n\t\t]\n\t}"
done
echo -e ${module_shards_string}"\n]"
}
function modules_builder
{
modules_string="modules = [\n\t"
count=1
for name in ${FRIENDLY_MODULE_NAMES[@]} ; do
modules_string="${modules_string}\n\t{\n\t\tname = \"${name}\"\n\t\tnamespace = \"${MODULE_NAMESPACES[${count}]}\"\n\t\tshard-strategy = \"module\"\n\t},"
count=$[count + 1]
done
# using ::-1 below to remove the extra comma we get from the above loop
echo -e ${modules_string::-1}"\n]"
}
function get_index ()
{
# Determine if the local IP address is in the CONTROLLER_LIST
# and its index in the list. Return the index.
local MY_IP=$1
shift
local IP_ADDRS=("$@")
local COUNTER=1
for IP in ${IP_ADDRS[@]} ;
do
if [ "$MY_IP" == "$IP" ]; then
echo "$COUNTER"
return
fi
COUNTER=$[$COUNTER + 1]
done
echo "$COUNTER"
}
function get_local_ip_addresses
{
# Get the local node's IP addresses as list
LOCAL_IPS=()
for IP in `hostname -I`
do
LOCAL_IPS+=("$IP")
done
echo ${LOCAL_IPS[@]}
}
function get_cli_params
{
# Check if params have been supplied
CONTROLLER_LIST=$*
# Verify we have controller list
test "${CONTROLLER_LIST}" == "" && usage "Missing controller list"
# Create the list of controllers from the CONTROLLER_LIST variable
CONTROLLERIPS=( ${CONTROLLER_LIST//,/ } )
# Get the local node's IP addresses
LOCAL_IPS=$(get_local_ip_addresses)
for CONTROLLER_IP in ${LOCAL_IPS[@]} ;
do
INDEX=$(get_index $CONTROLLER_IP ${CONTROLLERIPS[@]})
if [ ${INDEX} -le ${#CONTROLLERIPS[@]} ] ; then
break
fi
done
test ${INDEX} -le 0 -o ${INDEX} -gt ${#CONTROLLERIPS[@]} && \
usage "Controller's local IP address not in the controller list"
CONTROLLER_ID="member-${INDEX}"
}
function modify_conf_files
{
BIN_DIR=`dirname $0`
CUSTOM_SHARD_CONFIG_FILE=${BIN_DIR}'/custom_shard_config.txt'
echo "Configuring unique name in akka.conf"
sed -i -e "/roles[ ]*=/ { :loop1 /.*\]/ b done1; N; b loop1; :done1 s/roles.*\]/roles = [\"${CONTROLLER_ID}\"]/}" ${AKKACONF}
echo "Configuring hostname in akka.conf"
sed -i -e "s/hostname[ ]*=.*\"/hostname = \"${CONTROLLER_IP}\"/" ${AKKACONF}
echo "Configuring data and rpc seed nodes in akka.conf"
sed -i -e "/seed-nodes[ ]*=/ { :loop2 /.*\]/ b done2; N; b loop2; :done2 s/seed-nodes.*opendaylight-cluster-data.*\]/seed-nodes = [${DATA_SEED_LIST}]/; s/seed-nodes.*odl-cluster-rpc.*\]/seed-nodes = [${RPC_SEED_LIST}]/}" ${AKKACONF}
if [ -f ${CUSTOM_SHARD_CONFIG_FILE} ]; then
source ${CUSTOM_SHARD_CONFIG_FILE}
if [ "${#FRIENDLY_MODULE_NAMES[@]}" -ne "${#MODULE_NAMESPACES[@]}" ]; then
echo -e "\ncustom shard config file \"${CUSTOM_SHARD_CONFIG_FILE}\" does not have the same number of FRIENDLY_MODULE_NAMES[] and MODULE_NAMESPACES[]\n"
exit 1
fi
module_shards_builder > ${MODULESHARDSCONF}
modules_builder > ${MODULESCONF}
cat ${MODULESCONF}
fi
echo "Configuring replication type in module-shards.conf"
sed -i -e "/^[^#].*replicas[ ]*=/ { :loop /.*\]/ b done; N; b loop; :done s/replicas.*\]/replicas = [${MEMBER_NAME_LIST}]/}" ${MODULESHARDSCONF}
}
function verify_configuration_files
{
# Constants
BIN_DIR=`dirname $0`
test ${BIN_DIR} == '.' && BIN_DIR=${PWD}
CONTROLLER_DIR=`dirname ${BIN_DIR}`
CONF_DIR=${CONTROLLER_DIR}/configuration/initial
AKKACONF=${CONF_DIR}/akka.conf
MODULESCONF=${CONF_DIR}/modules.conf
MODULESHARDSCONF=${CONF_DIR}/module-shards.conf
# Verify configuration files are present in expected location.
if [ ! -f ${AKKACONF} -o ! -f ${MODULESHARDSCONF} ]; then
# Check if the configuration files exist in the system
# directory, then copy them over.
ORIG_CONF_DIR=${CONTROLLER_DIR}/system/org/opendaylight/controller/sal-clustering-config
version=$(sed -n -e 's/.*<version>\(.*\)<\/version>/\1/p' ${ORIG_CONF_DIR}/maven-metadata-local.xml)
ORIG_CONF_DIR=${ORIG_CONF_DIR}/${version}
ORIG_AKKA_CONF=sal-clustering-config-${version}-akkaconf.xml
ORIG_MODULES_CONF=sal-clustering-config-${version}-moduleconf.xml
ORIG_MODULESHARDS_CONF=sal-clustering-config-${version}-moduleshardconf.xml
if [ -f ${ORIG_CONF_DIR}/${ORIG_AKKA_CONF} -a \
-f ${ORIG_CONF_DIR}/${ORIG_MODULES_CONF} -a \
-f ${ORIG_CONF_DIR}/${ORIG_MODULESHARDS_CONF} ]; then
cat <<EOF
NOTE: Cluster configuration files not found. Copying from
${ORIG_CONF_DIR}
EOF
mkdir -p ${CONF_DIR}
cp ${ORIG_CONF_DIR}/${ORIG_AKKA_CONF} ${AKKACONF}
cp ${ORIG_CONF_DIR}/${ORIG_MODULES_CONF} ${MODULESCONF}
cp ${ORIG_CONF_DIR}/${ORIG_MODULESHARDS_CONF} ${MODULESHARDSCONF}
else
cat << EOF
ERROR: Cluster configurations files not found. Please\
configure clustering feature.
EOF
exit 1
fi
fi
}
function main
{
get_cli_params $*
start_banner
verify_configuration_files
create_strings
modify_conf_files
end_banner
}
main $*
# vim: ts=4 sw=4 sts=4 et ft=sh :
|