Ansible Mariadb w/ Galera support

Adds initial support for Mariadb with Galera replication in Ansible
using the CONFIG_EXTERNAL methods.

Additionally, this refactors some of the Galera config script to allow
for reuse by CONFIG_EXTERNAL.

Partially Implements: blueprint ansible-service

Change-Id: I566fea0376ecca39fc8a5167f9ff9ff434ea7b7e
This commit is contained in:
Sam Yaple 2015-06-25 14:33:28 +00:00
parent 90d92347e8
commit efbfd7912b
17 changed files with 226 additions and 37 deletions

View File

@ -14,6 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# TODO(SamYaple): Provide idempotency for module (Note to self: pull logic from
# pervious bslurp module in yaodu)
DOCUMENTATION = '''
---
module: merge_configs

View File

@ -0,0 +1,21 @@
---
project_name: "mariadb"
####################
# Database
####################
database_cluster_name: "kolla"
####################
# Docker
####################
docker_database_registry: "{{ docker_registry }}"
docker_database_namespace: "{{ docker_namespace }}"
kolla_database_base_distro: "{{ kolla_base_distro }}"
kolla_database_install_type: "{{ kolla_install_type }}"
kolla_database_container_name: "galera"
docker_database_image: "{{ docker_database_registry }}{{ docker_database_namespace }}/{{ kolla_database_base_distro }}-{{ kolla_database_install_type }}-{{ kolla_database_container_name }}"
docker_database_tag: "{{ openstack_release }}"
docker_database_image_full: "{{ docker_database_image }}:{{ docker_database_tag }}"

View File

@ -0,0 +1,61 @@
---
- name: Creating temp file on localhost
local_action: shell echo 'None' > /tmp/kolla_mariadb_cluster
register: status
changed_when: False
failed_when: status.rc != 0
always_run: True
run_once: True
# TODO(SamYaple): Improve failed_when check
- name: Checking if a previous cluster exists
command: docker exec mariadb stat /var/lib/mysql/grastate.dat
register: exists
changed_when: False
failed_when: False
always_run: True
run_once: True
- name: Writing hostname of host with existing cluster files to temp file
local_action: shell echo "{{ ansible_hostname }}" > /tmp/kolla_mariadb_cluster
register: status
changed_when: False
failed_when: status.rc != 0
always_run: True
when: exists.rc == 0
- name: Registering host from temp file
set_fact:
delegate_host: "{{ lookup('file', '/tmp/kolla_mariadb_cluster') }}"
- name: Cleaning up temp file on localhost
local_action: shell rm /tmp/kolla_mariadb_cluster
register: status
changed_when: False
failed_when: status.rc != 0
always_run: True
run_once: True
- include: ../../start.yml
vars:
container_environment:
KOLLA_BOOTSTRAP:
container_image: "{{ docker_database_image_full }}"
container_name: "mariadb_data"
container_volumes:
- "/var/lib/mysql/"
container_command: "/bin/sleep infinity"
- include: ../../start.yml
vars:
container_environment:
KOLLA_BOOTSTRAP:
KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
DB_ROOT_PASSWORD: "{{ database_password }}"
container_image: "{{ docker_database_image_full }}"
container_name: "mariadb"
container_volumes:
- "{{ node_config_directory }}/mariadb/:/opt/kolla/mariadb/:ro"
container_volumes_from:
- "mariadb_data"
when: delegate_host == 'None' and inventory_hostname == groups['database'][0]

View File

@ -0,0 +1,10 @@
---
- include: ../../config.yml
vars:
config_source:
- "roles/database/templates/galera.cnf.j2"
config_template_dest:
- "{{ node_templates_directory }}/mariadb/galera.cnf_minimal"
config_dest: "{{ node_config_directory }}/mariadb/galera.cnf"

View File

@ -1,7 +1,13 @@
---
- name: Bringing up mariadb service(s)
docker_compose:
project_name: mariadb
compose_file: "{{ koalla_directory }}/compose/mariadb.yml"
command: up
no_recreate: true
- include: config.yml
- include: bootstrap.yml
- include: start.yml
- include: register.yml
# This will restart the container we initially used to bootstrap the cluster to
# make it match the other containers environment-wise. This also prevents a
# change from showing up when rerunning the playbooks
- include: start.yml

View File

@ -0,0 +1,18 @@
---
- name: Creating haproxy mysql user
mysql_user:
login_host: "{{ database_address }}"
login_user: "{{ database_user }}"
login_password: "{{ database_password }}"
name: "haproxy"
password: ""
host: "%"
priv: "*.*:USAGE"
register: status
until: status|success
retries: 10
delay: 5
- name: Cleaning up facts
set_fact:
delegate_host: "bootstraped"

View File

@ -0,0 +1,13 @@
---
- include: ../../start.yml
vars:
container_environment:
KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
container_image: "{{ docker_database_image_full }}"
container_name: "mariadb"
container_volumes:
- "{{ node_config_directory }}/mariadb/:/opt/kolla/mariadb/:ro"
container_volumes_from:
- "mariadb_data"
when: delegate_host != 'None' or
( delegate_host == 'None' and inventory_hostname != groups['database'][0])

View File

@ -0,0 +1,18 @@
[mysqld]
bind-address={{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
query_cache_size=0
query_cache_type=0
innodb_log_file_size=48M
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_address=gcomm://{% for host in groups['database'] %}{{ hostvars[host]['ansible_hostname'] }}{% if not loop.last %},{% endif %}{% endfor %}
wsrep_cluster_name="{{ database_cluster_name }}"
wsrep_node_address={{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}
wsrep_node_name={{ ansible_hostname }}
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth={{ database_user }}:{{ database_password }}
wsrep_slave_threads=4

View File

@ -9,22 +9,24 @@
# docker_api_version from docker-py, so we specify it here. This will be
# removed when the bugfix makes it downstream
- name: Starting the container
- name: Starting container(s)
docker:
command: "{{ container_command | default(None) }}"
detach: "{{ container_detach | default('True') }}"
env: "{{ container_environment }}"
env: "{{ container_environment | default(None) }}"
docker_api_version: "{{ docker_api_version }}"
image: "{{ container_image }}"
insecure_registry: "{{ docker_insecure_registry }}"
name: "{{ container_name }}"
net: host
net: "host"
password: "{{ docker_registry_password }}"
privileged: "{{ container_privileged | default('False') }}"
pull: "{{ docker_pull_policy }}"
registry: "{{ docker_registry }}"
restart_policy: "{{ docker_restart_policy }}"
restart_policy_retry: "{{ docker_restart_policy_retry }}"
state: reloaded
state: "reloaded"
username: "{{ docker_registry_username }}"
volumes: "{{ container_volumes }}"
volumes_from: "{{ container_volumes_from | default([]) }}"
run_once: "{{ run_once | default('False') }}"

View File

@ -21,7 +21,8 @@ RUN echo "[mariadb]" > /etc/yum.repos.d/MariaDB.repo && \
tar \
expect
COPY config-galera.sh /opt/kolla/config-galera.sh
COPY start.sh /start.sh
COPY config-galera.sh /opt/kolla/config/
COPY config-internal.sh config-external.sh /opt/kolla/
COPY start.sh /
CMD ["/start.sh"]

View File

@ -0,0 +1 @@
../../../common/galera/config-external.sh

View File

@ -0,0 +1 @@
../../../common/galera/config-internal.sh

View File

@ -175,19 +175,19 @@ set_configs() {
exec /opt/kolla/config-internal.sh
;;
CONFIG_EXTERNAL_COPY_ALWAYS)
source /opt/kolla/config-exernal.sh
source /opt/kolla/config-external.sh
;;
CONFIG_EXTERNAL_COPY_ONCE)
if [[ -f /configured ]]; then
echo 'INFO - This container has already been configured; Refusing to copy new configs'
return
else
source /opt/kolla/config-external.sh
touch /configured
fi
source /opt/kolla/config-exernal.sh
touch /configured
;;
*)
echo '$CONFIG_STRATEGY is not set properly'
echo '$KOLLA_CONFIG_STRATEGY is not set properly'
exit 1
;;
esac

View File

@ -0,0 +1,8 @@
#!/bin/bash
# Cluster configuration
if [[ -f /opt/kolla/mariadb/galera.cnf ]]; then
cp /opt/kolla/mariadb/galera.cnf /etc/my.cnf.d/galera.cnf
chown mysql: /etc/my.cnf.d/galera.cnf
chmod 0600 /etc/my.cnf.d/galera.cnf
fi

View File

@ -1,13 +1,5 @@
#!/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"
@ -30,8 +22,9 @@ function configure_files {
crudini --set $CFG mariadb wsrep_sst_method "${DB_CLUSTER_WSREP_METHOD}"
}
function bootstrap_database {
mysqld_safe &
function bootstrap_db {
mysqld_safe --wsrep-new-cluster &
# Waiting for deamon
sleep 10
expect -c '
@ -54,11 +47,14 @@ function bootstrap_database {
expect "Reload privilege tables now?"
send "y\r"
expect eof'
mysql -u root --password="${DB_ROOT_PASSWORD}" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '${DB_ROOT_PASSWORD}' WITH GRANT OPTION;"
mysql -u root --password="${DB_ROOT_PASSWORD}" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '${DB_ROOT_PASSWORD}' WITH GRANT OPTION;"
mysqladmin -p"${DB_ROOT_PASSWORD}" shutdown
}
function configure_db {
bootstrap_database
bootstrap_db
echo "GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY '$DB_ROOT_PASSWORD' ;" > $DB_CLUSTER_INIT_SQL
@ -81,7 +77,7 @@ function populate_db {
if [[ $(ls /var/lib/mysql) == "" ]]; then
echo "POPULATING NEW DB"
mysql_install_db
chown -R mysql /var/lib/mysql
chown -R mysql: /var/lib/mysql
else
echo "DB ALREADY EXISTS"
fi

View File

@ -0,0 +1,20 @@
#!/bin/bash
. /opt/kolla/kolla-common.sh
. /opt/kolla/config-galera.sh
check_required_vars DB_CLUSTER_BIND_ADDRESS DB_CLUSTER_NAME DB_CLUSTER_NODES \
DB_ROOT_PASSWORD DB_CLUSTER_WSREP_METHOD DB_CLUSTER_INIT_DB
CFG=/etc/my.cnf.d/server.cnf
DB_CLUSTER_INIT_SQL=/tmp/mysql-first-time.sql
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

View File

@ -1,15 +1,25 @@
#!/bin/bash
. /opt/kolla/kolla-common.sh
. /opt/kolla/config-galera.sh
set -o errexit
check_required_vars DB_CLUSTER_INIT_DB
prepare_db
CMD="/usr/bin/mysqld_safe"
ARGS=""
if [[ "${DB_CLUSTER_INIT_DB}" == "true" ]] && ! [[ -a /var/lib/mysql/cluster.exists ]]; then
DB_CLUSTER_IS_MASTER_NODE="--wsrep-new-cluster"
# loading common functions
source /opt/kolla/kolla-common.sh
# config-internal script exec out of this function, it does not return here
set_configs
# loading functions
source /opt/kolla/config/config-galera.sh
# This catches all cases of the BOOTSTRAP variable being set, including empty
if [[ "${!KOLLA_BOOTSTRAP[@]}" ]] && [[ ! -e /var/lib/mysql/cluster.exists ]]; then
ARGS="--wsrep-new-cluster"
touch /var/lib/mysql/cluster.exists
populate_db
bootstrap_db
fi
mysqld_safe --init-file=$DB_CLUSTER_INIT_SQL $DB_CLUSTER_IS_MASTER_NODE
exec $CMD $ARGS