summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--opendaylight/neon/neon-alpine/pom.xml7
-rw-r--r--opendaylight/neon/neon-alpine/src/main/docker/Dockerfile3
-rwxr-xr-xopendaylight/neon/neon-alpine/src/main/odlscripts/configure-cluster-ipdetect.sh265
-rwxr-xr-xopendaylight/neon/neon-alpine/src/main/odlscripts/configure_cluster.sh228
-rwxr-xr-xopendaylight/neon/neon-alpine/src/main/odlscripts/custom_shard_config.txt17
-rwxr-xr-xopendaylight/neon/neon-alpine/src/main/odlscripts/set_persistence.sh111
6 files changed, 631 insertions, 0 deletions
diff --git a/opendaylight/neon/neon-alpine/pom.xml b/opendaylight/neon/neon-alpine/pom.xml
index 072e884e..dc1e8b96 100644
--- a/opendaylight/neon/neon-alpine/pom.xml
+++ b/opendaylight/neon/neon-alpine/pom.xml
@@ -95,6 +95,13 @@
</includes>
<filtering>true</filtering>
</resource>
+ <resource>
+ <directory>src/main/odlscripts</directory>
+ <includes>
+ <include>*</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
</resources>
</configuration>
</execution>
diff --git a/opendaylight/neon/neon-alpine/src/main/docker/Dockerfile b/opendaylight/neon/neon-alpine/src/main/docker/Dockerfile
index 054a44f7..bd6ff4ae 100644
--- a/opendaylight/neon/neon-alpine/src/main/docker/Dockerfile
+++ b/opendaylight/neon/neon-alpine/src/main/docker/Dockerfile
@@ -15,6 +15,9 @@ RUN mkdir -p /opt/odl \
&& ln -s /opt/opendaylight /opt/opendaylight/${odl.karaf.artifactId}-${ccsdk.opendaylight.version} \
&& ln -s /opt/opendaylight /opt/opendaylight/current
+# Add missing scripts see SDNC-1056
+COPY configure_cluster.sh configure-cluster-ipdetect.sh custom_shard_config.txt set_persistence.sh $ODL_HOME/bin/
+RUN chmod 755 $ODL_HOME/bin/configure_cluster.sh $ODL_HOME/bin/configure-cluster-ipdetect.sh $ODL_HOME/bin/set_persistence.sh $ODL_HOME/bin/custom_shard_config.txt
# ENTRYPOINT exec /opt/opendaylight/bin/karaf
EXPOSE 8181
diff --git a/opendaylight/neon/neon-alpine/src/main/odlscripts/configure-cluster-ipdetect.sh b/opendaylight/neon/neon-alpine/src/main/odlscripts/configure-cluster-ipdetect.sh
new file mode 100755
index 00000000..7b97ef96
--- /dev/null
+++ b/opendaylight/neon/neon-alpine/src/main/odlscripts/configure-cluster-ipdetect.sh
@@ -0,0 +1,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 :
diff --git a/opendaylight/neon/neon-alpine/src/main/odlscripts/configure_cluster.sh b/opendaylight/neon/neon-alpine/src/main/odlscripts/configure_cluster.sh
new file mode 100755
index 00000000..c3f1a430
--- /dev/null
+++ b/opendaylight/neon/neon-alpine/src/main/odlscripts/configure_cluster.sh
@@ -0,0 +1,228 @@
+#!/bin/bash
+#
+# Copyright (c) 2015 Brocade Communications 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 <index> <seed_nodes_list>
+ - index: Integer within 1..N, where N is the number of seed nodes.
+ - seed_nodes_list: List of seed nodes, separated by comma or space.
+
+ The address at the provided index should belong this controller.
+ When running this script on multiple seed nodes, keep the
+ seed_node_list same, and vary the index from 1 through N.
+
+ 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
+
+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
+
+ if [ ${count} == 1 ]; then
+ # if no modules found in custom_shard_config.txt just close the bracket
+ echo -e ${modules_string}"\n]"
+ else
+ # using ::-1 below to remove the extra comma we get from the above loop
+ echo -e ${modules_string::-1}"\n]"
+ fi
+}
+
+function get_cli_params
+{
+ # Check if params have been supplied
+ test $# -eq 0 && usage
+
+ # First param is index, and rest are controller list
+ INDEX=$1; shift
+ 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//,/ } )
+
+ test ${INDEX} -le 0 -o ${INDEX} -gt ${#CONTROLLERIPS[@]} && \
+ usage "Invalid index"
+
+ CONTROLLER_ID="member-${INDEX}"
+ CONTROLLER_IP="${CONTROLLERIPS[((${INDEX} - 1))]}"
+}
+
+
+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 :
diff --git a/opendaylight/neon/neon-alpine/src/main/odlscripts/custom_shard_config.txt b/opendaylight/neon/neon-alpine/src/main/odlscripts/custom_shard_config.txt
new file mode 100755
index 00000000..e5363498
--- /dev/null
+++ b/opendaylight/neon/neon-alpine/src/main/odlscripts/custom_shard_config.txt
@@ -0,0 +1,17 @@
+# If this file has entries, they will be used to configure the module
+# shards that will be available. Otherwise, the default shards will
+# be used. Below, the commented lines are the current default shards
+# (inventory, network-topology, and toaster)
+#
+# These configurations are an array and the indexes need to increment
+# from 1,2,3...
+#
+# There is a FRIENDLY_MODULE_NAME[$index] that will map to the
+# MODULE_NAMESPACES[$index]
+#
+FRIENDLY_MODULE_NAMES[1]='inventory'
+MODULE_NAMESPACES[1]='urn:opendaylight:inventory'
+FRIENDLY_MODULE_NAMES[2]='topology'
+MODULE_NAMESPACES[2]='urn:TBD:params:xml:ns:yang:network-topology'
+FRIENDLY_MODULE_NAMES[3]='toaster'
+MODULE_NAMESPACES[3]='http://netconfcentral.org/ns/toaster'
diff --git a/opendaylight/neon/neon-alpine/src/main/odlscripts/set_persistence.sh b/opendaylight/neon/neon-alpine/src/main/odlscripts/set_persistence.sh
new file mode 100755
index 00000000..15c22717
--- /dev/null
+++ b/opendaylight/neon/neon-alpine/src/main/odlscripts/set_persistence.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+#
+# Copyright (c) 2015 Brocade Communications 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 enable or disable the config datastore
+ persistence. The default state is enabled. The user should
+ restart controller to apply changes. The script can be used
+ before starting controller for the first time.
+
+ Usage: $0 <on/off>
+
+EOF
+
+ exit 1
+}
+
+
+function end_banner
+{
+cat <<EOF
+################################################
+## NOTE: Manually restart controller to ##
+## apply configuration. ##
+################################################
+EOF
+}
+
+
+function get_cli_params
+{
+ # Check if params have been supplied
+ test $# -eq 0 && usage
+
+ # First param is on/off
+ SWITCH="$1"
+
+ # Verify we only have 1 param
+ test $# -ne 1 && usage "Too many parameters"
+}
+
+
+function modify_conf_file
+{
+ if [ "${SWITCH}" == "off" ]; then
+ echo "disabling config datastore persistence"
+ sed -i -e "s/^#persistent=true/persistent=false/" ${CLUSTERCONF}
+ elif [ "${SWITCH}" == "on" ]; then
+ echo "enabling config datastore persistence"
+ sed -i -e "s/^persistent=false/#persistent=true/" ${CLUSTERCONF}
+ else
+ usage "Allowed values are on/off"
+ fi
+}
+
+
+function verify_configuration_file
+{
+ # Constants
+ BIN_DIR=`dirname $0`
+ test ${BIN_DIR} == '.' && BIN_DIR=${PWD}
+ CONTROLLER_DIR=`dirname ${BIN_DIR}`
+ CONF_DIR=${CONTROLLER_DIR}/etc
+ CLUSTERCONF=${CONF_DIR}/org.opendaylight.controller.cluster.datastore.cfg
+
+ # Verify configuration files are present in expected location.
+ if [ ! -f ${CLUSTERCONF} ]; 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_CLUSTER_CONF=sal-clustering-config-${version}-datastore.cfg
+
+ if [ -f ${ORIG_CONF_DIR}/${ORIG_CLUSTER_CONF} ]; then
+ cat <<EOF
+ NOTE: Cluster configuration file not found. Copying from
+ ${ORIG_CONF_DIR}
+EOF
+ cp ${ORIG_CONF_DIR}/${ORIG_CLUSTER_CONF} ${CLUSTERCONF}
+
+ else
+ usage "Cluster configuration file not found"
+ fi
+ fi
+}
+
+function main
+{
+ get_cli_params "$@"
+ verify_configuration_file
+ modify_conf_file
+ end_banner
+}
+
+main "$@"
+
+# vim: ts=4 sw=4 sts=4 et ft=sh :
+