diff --git a/ansible/library/merge_configs b/ansible/library/merge_configs index 9991833aaccd98aea2b810b7f23f077a55d4f0cf..b1baeb3d14370f130bc4b5ddfe0b834d1f1274c9 100644 --- a/ansible/library/merge_configs +++ b/ansible/library/merge_configs @@ -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 diff --git a/ansible/roles/database/defaults/main.yml b/ansible/roles/database/defaults/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..469ad83550a2d1d7084e5c8fab3318a23370454e --- /dev/null +++ b/ansible/roles/database/defaults/main.yml @@ -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 }}" diff --git a/ansible/roles/database/tasks/bootstrap.yml b/ansible/roles/database/tasks/bootstrap.yml new file mode 100644 index 0000000000000000000000000000000000000000..4a46ee7cb08370d754037edefc8ed1862a39d7cc --- /dev/null +++ b/ansible/roles/database/tasks/bootstrap.yml @@ -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] diff --git a/ansible/roles/database/tasks/config.yml b/ansible/roles/database/tasks/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..a5f55483f5ed2bf663a42130703583188091cc42 --- /dev/null +++ b/ansible/roles/database/tasks/config.yml @@ -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" diff --git a/ansible/roles/database/tasks/main.yml b/ansible/roles/database/tasks/main.yml index 559b4bd1ccef6f71b681caae3df91eb93fc49d40..c7474dde55542051310c54f13667dabe070b561e 100644 --- a/ansible/roles/database/tasks/main.yml +++ b/ansible/roles/database/tasks/main.yml @@ -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 diff --git a/ansible/roles/database/tasks/register.yml b/ansible/roles/database/tasks/register.yml new file mode 100644 index 0000000000000000000000000000000000000000..ba6021090d7d7f590f52894c5bc2b73bac605d51 --- /dev/null +++ b/ansible/roles/database/tasks/register.yml @@ -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" diff --git a/ansible/roles/database/tasks/start.yml b/ansible/roles/database/tasks/start.yml new file mode 100644 index 0000000000000000000000000000000000000000..e60d49d4e1c9c4b009bf4d0ef1a766ae45b324f4 --- /dev/null +++ b/ansible/roles/database/tasks/start.yml @@ -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]) diff --git a/ansible/roles/database/templates/galera.cnf.j2 b/ansible/roles/database/templates/galera.cnf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..9d9d725d4ccbc32895986bd7cd98dd268b806841 --- /dev/null +++ b/ansible/roles/database/templates/galera.cnf.j2 @@ -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 diff --git a/ansible/roles/start.yml b/ansible/roles/start.yml index 44d9b0c67cac40dd8f36bcee2a2f6cb5f2077f03..8aadfb3fc25fa2ed78226d2304b14841dcc3122c 100644 --- a/ansible/roles/start.yml +++ b/ansible/roles/start.yml @@ -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') }}" diff --git a/docker/centos/binary/galera/Dockerfile b/docker/centos/binary/galera/Dockerfile index ce5477097bde7d38090e494db54ae7e03c9f7cb5..6e0e90f2580faa87c0dad34ddf8d2d0aba15e883 100644 --- a/docker/centos/binary/galera/Dockerfile +++ b/docker/centos/binary/galera/Dockerfile @@ -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"] diff --git a/docker/centos/binary/galera/config-external.sh b/docker/centos/binary/galera/config-external.sh new file mode 120000 index 0000000000000000000000000000000000000000..72a04836e71ac3aaa16b16ef11b67fa8a2b1641f --- /dev/null +++ b/docker/centos/binary/galera/config-external.sh @@ -0,0 +1 @@ +../../../common/galera/config-external.sh \ No newline at end of file diff --git a/docker/centos/binary/galera/config-internal.sh b/docker/centos/binary/galera/config-internal.sh new file mode 120000 index 0000000000000000000000000000000000000000..edab3d51fb6c1abf7aee5ec81c1a5462ef503c38 --- /dev/null +++ b/docker/centos/binary/galera/config-internal.sh @@ -0,0 +1 @@ +../../../common/galera/config-internal.sh \ No newline at end of file diff --git a/docker/common/base/kolla-common.sh b/docker/common/base/kolla-common.sh index bd6a539a0b25b53fb78c877d89122fdd4e63b66d..5c07b375de4f6f07cc0a58f763ba7a517f1c8fba 100644 --- a/docker/common/base/kolla-common.sh +++ b/docker/common/base/kolla-common.sh @@ -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 diff --git a/docker/common/galera/config-external.sh b/docker/common/galera/config-external.sh new file mode 100644 index 0000000000000000000000000000000000000000..a90f7fe6f3a9cf5160c2768f9686807f0d38081a --- /dev/null +++ b/docker/common/galera/config-external.sh @@ -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 diff --git a/docker/common/galera/config-galera.sh b/docker/common/galera/config-galera.sh index 9cbd2c7642724b894ad2f6be31519e5cca228ff9..8aab3cfe11cff8361ff7ef36e3f70415ee032579 100755 --- a/docker/common/galera/config-galera.sh +++ b/docker/common/galera/config-galera.sh @@ -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 diff --git a/docker/common/galera/config-internal.sh b/docker/common/galera/config-internal.sh new file mode 100755 index 0000000000000000000000000000000000000000..5e55dcde448ebb2e0af442b3d697c9562de1bb97 --- /dev/null +++ b/docker/common/galera/config-internal.sh @@ -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 + diff --git a/docker/common/galera/start.sh b/docker/common/galera/start.sh index 2ac683f110d7c66d879f35e575034d9fe2f988a2..42bd882b1a11e3d6b2044d3d0eb44da0829ef563 100755 --- a/docker/common/galera/start.sh +++ b/docker/common/galera/start.sh @@ -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