From abbee7dbcac828840a7f0cca914c8d9a570180d1 Mon Sep 17 00:00:00 2001
From: Michal Stachowski <michal.stachowski@intel.com>
Date: Fri, 19 Jun 2015 16:14:34 +0200
Subject: [PATCH] Galera container

This changes are providing support for galera cluster. It's important for
project to has got support for database cluster as a one of the steps to
providing High Avability(HA) in Kolla project

Change-Id: If51bb88ab05972d3b8aa8abbbbd2a5480213a10e
Implemented: blueprint galera-container
---
 compose/galeradb.yml                         | 15 ++++
 docker/centos/binary/galera/Dockerfile       | 27 ++++++
 docker/centos/binary/galera/build            |  1 +
 docker/centos/binary/galera/config-galera.sh | 94 ++++++++++++++++++++
 docker/centos/binary/galera/start.sh         | 14 +++
 docs/integration-guide.md                    |  5 ++
 tools/genenv                                 | 12 +++
 7 files changed, 168 insertions(+)
 create mode 100644 compose/galeradb.yml
 create mode 100644 docker/centos/binary/galera/Dockerfile
 create mode 120000 docker/centos/binary/galera/build
 create mode 100755 docker/centos/binary/galera/config-galera.sh
 create mode 100755 docker/centos/binary/galera/start.sh

diff --git a/compose/galeradb.yml b/compose/galeradb.yml
new file mode 100644
index 0000000000..2a40e37e7c
--- /dev/null
+++ b/compose/galeradb.yml
@@ -0,0 +1,15 @@
+galeradbdata:
+  image: kollaglue/centos-rdo-mariadb-data:latest
+  name: galeradb-data
+  restart: on-failure
+
+galeraapp:
+  image: kollaglue/centos-rdo-galera:latest
+  name: galera-app
+  restart: always
+  net: "host"
+  privileged: true
+  env_file:
+    - openstack.env
+  volumes_from:
+    - galeradbdata
\ No newline at end of file
diff --git a/docker/centos/binary/galera/Dockerfile b/docker/centos/binary/galera/Dockerfile
new file mode 100644
index 0000000000..ce5477097b
--- /dev/null
+++ b/docker/centos/binary/galera/Dockerfile
@@ -0,0 +1,27 @@
+FROM %%KOLLA_NAMESPACE%%/%%KOLLA_PREFIX%%base:%%KOLLA_TAG%%
+MAINTAINER Kolla Project (https://launchpad.net/kolla)
+
+RUN echo "[mariadb]" > /etc/yum.repos.d/MariaDB.repo && \
+   echo "name = MariaDB" >> /etc/yum.repos.d/MariaDB.repo && \
+   echo "baseurl = http://yum.mariadb.org/10.0/centos7-amd64" >> /etc/yum.repos.d/MariaDB.repo && \
+   echo "gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB" >> /etc/yum.repos.d/MariaDB.repo && \
+   echo "gpgcheck=1" >> /etc/yum.repos.d/MariaDB.repo && \
+   yum install -y \
+      http://www.percona.com/redir/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm && \
+   sed -i 's|$releasever|centos/latest|g' /etc/yum.repos.d/percona-release.repo && \
+   yum install -y \
+      MariaDB-Galera-server \
+      MariaDB-client \
+      rsync \
+      galera \
+      socat \
+      hostname \
+      percona-xtrabackup \
+      pv \
+      tar \
+      expect
+
+COPY config-galera.sh /opt/kolla/config-galera.sh
+COPY start.sh /start.sh
+
+CMD ["/start.sh"]
diff --git a/docker/centos/binary/galera/build b/docker/centos/binary/galera/build
new file mode 120000
index 0000000000..8d652f7ee2
--- /dev/null
+++ b/docker/centos/binary/galera/build
@@ -0,0 +1 @@
+../../../../tools/build-docker-image
\ No newline at end of file
diff --git a/docker/centos/binary/galera/config-galera.sh b/docker/centos/binary/galera/config-galera.sh
new file mode 100755
index 0000000000..f0ab542e15
--- /dev/null
+++ b/docker/centos/binary/galera/config-galera.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+
+. /opt/kolla/kolla-common.sh
+
+check_required_vars DB_CLUSTER_BIND_ADDRESS DB_CLUSTER_NAME DB_CLUSTER_NODES \
+                    DB_ROOT_PASSWORD DB_CLUSTER_WSREP_METHOD
+
+CFG=/etc/my.cnf.d/server.cnf
+DB_CLUSTER_INIT_SQL=/tmp/mysql-first-time.sql
+
+function configure_files {
+    crudini --set $CFG mariadb bind-address "${DB_CLUSTER_BIND_ADDRESS}"
+    crudini --set $CFG mariadb binlog_format "ROW"
+    crudini --set $CFG mariadb character-set-server "utf8"
+    crudini --set $CFG mariadb collation-server "utf8_general_ci"
+    crudini --set $CFG mariadb datadir "/var/lib/mysql"
+    crudini --set $CFG mariadb default-storage-engine "innodb"
+    crudini --set $CFG mariadb init-connect "'SET NAMES utf8'"
+    crudini --set $CFG mariadb innodb_autoinc_lock_mode "2"
+    crudini --set $CFG mariadb innodb_file_per_table 1
+    crudini --set $CFG mariadb innodb_flush_log_at_trx_commit "2"
+    crudini --set $CFG mariadb innodb_locks_unsafe_for_binlog "1"
+    crudini --set $CFG mariadb innodb_log_file_size "100M"
+    crudini --set $CFG mariadb query_cache_size "0"
+    crudini --set $CFG mariadb query_cache_type "0"
+    crudini --set $CFG mariadb wsrep_cluster_address "gcomm://${DB_CLUSTER_NODES}"
+    crudini --set $CFG mariadb wsrep_cluster_name "${DB_CLUSTER_NAME}"
+    crudini --set $CFG mariadb wsrep_provider "/usr/lib64/galera/libgalera_smm.so"
+    crudini --set $CFG mariadb wsrep_sst_auth "'root:${DB_ROOT_PASSWORD}'"
+    crudini --set $CFG mariadb wsrep_sst_method "${DB_CLUSTER_WSREP_METHOD}"
+}
+
+function bootstrap_database() {
+    mysqld_safe &
+    # Waiting for deamon
+    sleep 10
+    expect -c '
+    set timeout 10
+    spawn mysql_secure_installation
+    expect "Enter current password for root (enter for none):"
+    send "\r"
+    expect "Set root password?"
+    send "y\r"
+    expect "New password:"
+    send "'"${DB_ROOT_PASSWORD}"'\r"
+    expect "Re-enter new password:"
+    send "'"${DB_ROOT_PASSWORD}"'\r"
+    expect "Remove anonymous users?"
+    send "y\r"
+    expect "Disallow root login remotely?"
+    send "n\r"
+    expect "Remove test database and access to it?"
+    send "y\r"
+    expect "Reload privilege tables now?"
+    send "y\r"
+    expect eof'
+    mysqladmin -p"${DB_ROOT_PASSWORD}" shutdown
+}
+
+function configure_db {
+    bootstrap_database
+
+    echo "GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY '$DB_ROOT_PASSWORD' ;" > $DB_CLUSTER_INIT_SQL
+
+    if [ "$MARIADB_DATABASE" ]; then
+        echo "CREATE DATABASE IF NOT EXISTS $MARIADB_DATABASE ;" >> $DB_CLUSTER_INIT_SQL
+    fi
+
+    if [ "$MARIADB_USER" -a "$MARIADB_PASSWORD" ]; then
+        echo "CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$MARIADB_PASSWORD' ;" >> $DB_CLUSTER_INIT_SQL
+
+        if [ "$MARIADB_DATABASE" ]; then
+            echo "GRANT ALL ON $MARIADB_DATABASE.* TO '$MARIADB_USER'@'%' ;" >> $DB_CLUSTER_INIT_SQL
+        fi
+    fi
+
+    echo "FLUSH PRIVILEGES" >> $DB_CLUSTER_INIT_SQL
+}
+
+function populate_db {
+    if [[ $(ls /var/lib/mysql) == "" ]]; then
+        echo "POPULATING NEW DB"
+        mysql_install_db
+        chown -R mysql /var/lib/mysql
+    else
+        echo "DB ALREADY EXISTS"
+    fi
+}
+
+function prepare_db {
+    populate_db
+    configure_db
+    configure_files
+}
diff --git a/docker/centos/binary/galera/start.sh b/docker/centos/binary/galera/start.sh
new file mode 100755
index 0000000000..9288b77cc7
--- /dev/null
+++ b/docker/centos/binary/galera/start.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+. /opt/kolla/kolla-common.sh
+. /opt/kolla/config-galera.sh
+
+check_required_vars DB_CLUSTER_INIT_DB
+prepare_db
+
+if [[ "${DB_CLUSTER_INIT_DB}" == "true" ]] && ! [[ -a /var/lib/mysql/cluster.exists ]]; then
+    DB_CLUSTER_IS_MASTER_NODE="--wsrep-new-cluster"
+    touch /var/lib/mysql/cluster.exists
+fi
+
+mysqld_safe --init-file=$DB_CLUSTER_INIT_SQL $DB_CLUSTER_IS_MASTER_NODE
\ No newline at end of file
diff --git a/docs/integration-guide.md b/docs/integration-guide.md
index 4794508ff6..eb7c475b19 100644
--- a/docs/integration-guide.md
+++ b/docs/integration-guide.md
@@ -56,6 +56,11 @@ all containers.  This allows a simple method of ensuring every type of node
     ADMIN_USER_PASSWORD=<steakfordinner> - The admin user password
     ADMIN_TENANT_NAME=<admin> - tenant name
     FLAT_INTERFACE=<eth1> - nova networking flat interface device name
+    DB_CLUSTER_BIND_ADDRESS=<subnet address/IP> - Defaults to 0.0.0.0. Listening address for database.
+    DB_CLUSTER_INIT_DB=<true|false> - Defaults to false. Configures if Galera should be initialized.
+    DB_CLUSTER_NAME=<cluster-name>. Defaults to kollacluster. Galera cluster name.
+    DB_CLUSTER_NODES=<cluster-nodes>. Defaults to none. List of nodes in Galera cluster, separated by comma(IP address or hostname).
+    DB_CLUSTER_WSREP_METHOD=<rsync|mysqldump|xtremebackup|xtremebackup-v2> - Defaults to mysqldump. Galera replication method.
     GLANCE_API_SERVICE_HOST=<IP> - address where glance API is running>
     GLANCE_DB_NAME=<glance> - DB name of glance service
     GLANCE_DB_PASSWORD=<password> - <Glance DB password>
diff --git a/tools/genenv b/tools/genenv
index 28b4ef8a41..e7a30a9c49 100755
--- a/tools/genenv
+++ b/tools/genenv
@@ -27,6 +27,13 @@ HOST_IP=$MY_IP
 MARIADB_ROOT_PASSWORD=kolla
 PASSWORD=12345
 
+# Galera
+DB_CLUSTER_BIND_ADDRESS=0.0.0.0
+DB_CLUSTER_INIT_DB=false
+DB_CLUSTER_NAME=kollacluster
+DB_CLUSTER_NODES=
+DB_CLUSTER_WSREP_METHOD=mysqldump
+
 # Host
 ADMIN_TENANT_NAME=admin
 PUBLIC_IP=$HOST_IP
@@ -253,6 +260,11 @@ DESIGNATE_POOLMAN_TARGETS=$DESIGNATE_POOLMAN_TARGETS
 DESIGNATE_POOLMAN_NSS=$DESIGNATE_POOLMAN_NSS
 DESIGNATE_INITDB=$DESIGNATE_INITDB
 DESIGNATE_ALLOW_RECURSION=$DESIGNATE_ALLOW_RECURSION
+DB_CLUSTER_BIND_ADDRESS=$DB_CLUSTER_BIND_ADDRESS
+DB_CLUSTER_INIT_DB=$DB_CLUSTER_INIT_DB
+DB_CLUSTER_NAME=$DB_CLUSTER_NAME
+DB_CLUSTER_NODES=$DB_CLUSTER_NODES
+DB_CLUSTER_WSREP_METHOD=$DB_CLUSTER_WSREP_METHOD
 EOF
 echo Please customize your FLAT_INTERFACE to a different network then your
 echo main network. The FLAT_INTERFACE is used for inter-VM communication.