From 214ac7e6084583f703041fdfd19d67dda9417274 Mon Sep 17 00:00:00 2001
From: Michal Stachowski <michal.stachowski@intel.com>
Date: Wed, 24 Jun 2015 14:10:10 +0200
Subject: [PATCH] RabbitMQ container with HA support

This is new RabbitMQ container with support for HA. It's next step for
provide HA support in Kolla project. RabbitMQ is supporting now
active/active model and It's ready for active/passive model.

Change-Id: I2eb6c65f6268ee96d377e72cf880a01c8042559e
Implements: blueprint rabbitmq-ha
---
 docker/centos/binary/rabbitmq/Dockerfile      | 20 +++----
 .../centos/binary/rabbitmq/config-rabbit.sh   | 56 +++++++++++++++++++
 docker/common/rabbitmq/rabbitmq-env.conf      |  2 +-
 docker/common/rabbitmq/rabbitmq.config        |  1 +
 docker/common/rabbitmq/start.sh               | 21 +------
 docs/integration-guide.md                     |  2 +
 tools/genenv                                  |  4 ++
 7 files changed, 74 insertions(+), 32 deletions(-)
 create mode 100644 docker/centos/binary/rabbitmq/config-rabbit.sh

diff --git a/docker/centos/binary/rabbitmq/Dockerfile b/docker/centos/binary/rabbitmq/Dockerfile
index 9212d15ebf..f42bc8307e 100644
--- a/docker/centos/binary/rabbitmq/Dockerfile
+++ b/docker/centos/binary/rabbitmq/Dockerfile
@@ -1,18 +1,14 @@
 FROM %%KOLLA_NAMESPACE%%/%%KOLLA_PREFIX%%base:%%KOLLA_TAG%%
 MAINTAINER Kolla Project (https://launchpad.net/kolla)
 
-# Install required packages
-RUN yum -y install rabbitmq-server hostname && yum clean all
+RUN yum -y install \
+   hostname \
+   rabbitmq-server && \
+   yum clean all && \
+   /usr/lib/rabbitmq/bin/rabbitmq-plugins enable rabbitmq_management
 
-# Run the management plugin
-RUN /usr/lib/rabbitmq/bin/rabbitmq-plugins enable rabbitmq_management
+COPY rabbitmq.config rabbitmq-env.conf /etc/rabbitmq/
+COPY config-rabbit.sh /opt/kolla/config-rabbit.sh
+COPY start.sh /start.sh
 
-# Copy Rabbit conf files
-ADD rabbitmq.config /etc/rabbitmq/
-ADD rabbitmq-env.conf /etc/rabbitmq/
-
-# Copy start-up script
-ADD start.sh /start.sh
-
-# Start Rabbit through the start script
 CMD ["/start.sh"]
diff --git a/docker/centos/binary/rabbitmq/config-rabbit.sh b/docker/centos/binary/rabbitmq/config-rabbit.sh
new file mode 100644
index 0000000000..f78cd06568
--- /dev/null
+++ b/docker/centos/binary/rabbitmq/config-rabbit.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+. /opt/kolla/kolla-common.sh
+
+check_required_vars RABBITMQ_CLUSTER_COOKIE RABBITMQ_CLUSTER_NODES \
+                    RABBITMQ_LOG_BASE RABBITMQ_PASS RABBITMQ_USER
+
+RABBITMQ_CLUSTER_CONFIGURATION=""
+
+function configure_files {
+
+    sed -i '
+        s|@RABBITMQ_USER@|'"$RABBITMQ_USER"'|g
+        s|@RABBITMQ_PASS@|'"$RABBITMQ_PASS"'|g
+        s|@RABBITMQ_CLUSTER_NODES@|'"$RABBITMQ_CLUSTER_CONFIGURATION"'|g
+    ' /etc/rabbitmq/rabbitmq.config
+
+    sed -i '
+        s|@RABBITMQ_LOG_BASE@|'"$RABBITMQ_LOG_BASE"'|g
+    ' /etc/rabbitmq/rabbitmq-env.conf
+}
+
+function configure_cluster {
+    echo "${RABBITMQ_CLUSTER_COOKIE}" > /var/lib/rabbitmq/.erlang.cookie
+    chown rabbitmq /var/lib/rabbitmq/.erlang.cookie
+    chmod 700 /var/lib/rabbitmq/.erlang.cookie
+
+    HOSTNAME=""
+    IP_ADDRESS=""
+    DELIMETER=""
+
+    for node in ${RABBITMQ_CLUSTER_NODES}; do
+        HOSTNAME=`echo ${node} | cut -d'@' -f1`
+        IP_ADDRESS=`echo ${node} | cut -d'@' -f2`
+        CLUSTER_NODES="${CLUSTER_NODES}${DELIMETER}rabbit@${HOSTNAME}"
+        echo "${IP_ADDRESS} ${HOSTNAME}" >> /etc/hosts
+        DELIMETER=","
+    done
+    RABBITMQ_CLUSTER_CONFIGURATION="{cluster_nodes, {[$CLUSTER_NODES], disc}},"
+}
+
+function configure_rabbit {
+    if [ "$RABBITMQ_CLUSTER_NODES" ] && [ "$RABBITMQ_CLUSTER_COOKIE" ]; then
+        configure_cluster
+    elif [ "$RABBITMQ_SERVICE_HOST" ]; then
+        # work around:
+        # https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/653405
+        echo "${RABBITMQ_SERVICE_HOST} `/usr/bin/hostname -s`" > /etc/hosts
+    else
+        echo "You need RABBITMQ_SERVICE_HOST or RABBITMQ_CLUSTER_NODES & " \
+            " RABBITMQ_CLUSTER_COOKIES variables"
+        exit 1
+    fi
+
+    configure_files
+}
diff --git a/docker/common/rabbitmq/rabbitmq-env.conf b/docker/common/rabbitmq/rabbitmq-env.conf
index e76f18f0b1..a8926619c8 100644
--- a/docker/common/rabbitmq/rabbitmq-env.conf
+++ b/docker/common/rabbitmq/rabbitmq-env.conf
@@ -1,2 +1,2 @@
-RABBITMQ_NODENAME=@RABBITMQ_NODENAME@
+RABBITMQ_NODENAME=rabbit
 RABBITMQ_LOG_BASE=@RABBITMQ_LOG_BASE@
diff --git a/docker/common/rabbitmq/rabbitmq.config b/docker/common/rabbitmq/rabbitmq.config
index 15a47eba18..7cd0f68298 100644
--- a/docker/common/rabbitmq/rabbitmq.config
+++ b/docker/common/rabbitmq/rabbitmq.config
@@ -1,5 +1,6 @@
 [
   {rabbit, [
+    @RABBITMQ_CLUSTER_CONFIGURATION@
     {default_user, <<"@RABBITMQ_USER@">>},
     {default_pass, <<"@RABBITMQ_PASS@">>}
   ]},
diff --git a/docker/common/rabbitmq/start.sh b/docker/common/rabbitmq/start.sh
index f70c348668..4e76e382f9 100755
--- a/docker/common/rabbitmq/start.sh
+++ b/docker/common/rabbitmq/start.sh
@@ -1,24 +1,7 @@
 #!/bin/bash
 
-set -e
+. /opt/kolla/config-rabbit.sh
 
-: ${RABBITMQ_USER:=guest}
-: ${RABBITMQ_PASS:=guest}
-: ${RABBITMQ_NODENAME:=rabbit}
-: ${RABBITMQ_LOG_BASE:=/var/log/rabbitmq}
-
-sed -i '
-    s|@RABBITMQ_USER@|'"$RABBITMQ_USER"'|g
-    s|@RABBITMQ_PASS@|'"$RABBITMQ_PASS"'|g
-' /etc/rabbitmq/rabbitmq.config
-
-sed -i '
-    s|@RABBITMQ_NODENAME@|'"$RABBITMQ_NODENAME"'|g
-    s|@RABBITMQ_LOG_BASE@|'"$RABBITMQ_LOG_BASE"'|g
-' /etc/rabbitmq/rabbitmq-env.conf
-
-# work around:
-#   https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/653405
-echo "${RABBITMQ_SERVICE_HOST} `/usr/bin/hostname -s`" > /etc/hosts
+configure_rabbit
 
 exec /usr/sbin/rabbitmq-server
diff --git a/docs/integration-guide.md b/docs/integration-guide.md
index e85dd61856..122f028670 100755
--- a/docs/integration-guide.md
+++ b/docs/integration-guide.md
@@ -123,6 +123,8 @@ all containers.  This allows a simple method of ensuring every type of node
     RABBITMQ_PASS=<rabbit> - The rabbitmq password used to join AMQP
     RABBITMQ_SERVICE_HOST=<IP> - The IP Address where the Rabbit service is running
     RABBITMQ_USER=<rabbit> - The RabbitMQ user name
+    RABBITMQ_CLUSTER_NODES=<rabbit-nodes> - Default to none. RabbitMQ cluster nodes list in format 'hostname1@IP1 hostname2@IP2' (without quotes)
+    RABBITMQ_CLUSTER_COOKIE=<rabbit-cookie> - Default to none. RabbitMQ cookie content. Alphabetical value here
     RABBIT_PASSWORD=<password> - The RabbitMQ password
     RABBIT_USERID=<rabbit> - The RabbitMQ user id on the host
     MAGNUM_DB_NAME=<magnum> - The Magnum database name
diff --git a/tools/genenv b/tools/genenv
index 501527e49e..b908d951b7 100755
--- a/tools/genenv
+++ b/tools/genenv
@@ -68,6 +68,8 @@ CINDER_SCHEDULER_LOG_FILE=
 
 # RabbitMQ
 RABBITMQ_SERVICE_HOST=$HOST_IP
+RABBITMQ_CLUSTER_NODES=
+RABBITMQ_CLUSTER_COOKIE=
 RABBIT_USER=guest
 RABBIT_PASSWORD=guest
 
@@ -298,6 +300,8 @@ PUBLIC_IP=$PUBLIC_IP
 RABBITMQ_PASS=$RABBIT_PASSWORD
 RABBITMQ_SERVICE_HOST=$RABBITMQ_SERVICE_HOST
 RABBITMQ_USER=$RABBIT_USER
+RABBITMQ_CLUSTER_NODES=$RABBITMQ_CLUSTER_NODES
+RABBITMQ_CLUSTER_COOKIE=$RABBITMQ_CLUSTER_COOKIE
 RABBIT_PASSWORD=$RABBIT_PASSWORD
 RABBIT_USERID=$RABBIT_USER
 DESIGNATE_DB_NAME=$DESIGNATE_DB_NAME
-- 
GitLab