diff --git a/.gitignore b/.gitignore index fd8e52a..c7cdbe1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vagrant* *.swp +*.retry diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..87bf772 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,45 @@ +env: + - PLATFORM='docker-jessie-default-mysql-master' ANSIBLE_VERSION='ansible>=2.3,<2.4' + - PLATFORM='docker-jessie-default-mariadb-master' ANSIBLE_VERSION='ansible>=2.3,<2.4' + - PLATFORM='docker-jessie-upstream-mariadb-master' ANSIBLE_VERSION='ansible>=2.3,<2.4' + - PLATFORM='docker-jessie-upstream-percona-master' ANSIBLE_VERSION='ansible>=2.3,<2.4' + - PLATFORM='docker-jessie-upstream-mariadbgalera-1' ANSIBLE_VERSION='ansible>=2.3,<2.4' + - PLATFORM='docker-stretch-default-mysql-master' ANSIBLE_VERSION='ansible>=2.3,<2.4' + - PLATFORM='docker-stretch-default-mariadb-master' ANSIBLE_VERSION='ansible>=2.3,<2.4' + - PLATFORM='docker-stretch-upstream-mariadb-master' ANSIBLE_VERSION='ansible>=2.3,<2.4' + - PLATFORM='docker-stretch-upstream-mariadbgalera-1' ANSIBLE_VERSION='ansible>=2.3,<2.4' + +matrix: + allow_failures: + - env: PLATFORM='docker-jessie-upstream-mariadbgalera-1' ANSIBLE_VERSION='ansible>=2.3,<2.4' + - env: PLATFORM='docker-stretch-upstream-mariadbgalera-1' ANSIBLE_VERSION='ansible>=2.3,<2.4' + fast_finish: true + +sudo: required + +dist: trusty + +language: python + +services: + - docker + +before_install: + - wget https://releases.hashicorp.com/vagrant/1.9.5/vagrant_1.9.5_x86_64.deb + - sudo dpkg -i vagrant_1.9.5_x86_64.deb + - vagrant plugin install vagrant-hostmanager + +install: + - pip install "$ANSIBLE_VERSION" + +script: + - VAGRANT_DEFAULT_PROVIDER=docker vagrant up $PLATFORM + - > + VAGRANT_DEFAULT_PROVIDER=docker vagrant provision $PLATFORM + | grep -q 'changed=0.*failed=0' + && (echo 'Idempotence test: pass' && exit 0) + || (echo 'Idempotence test: fail' && exit 1) + - VAGRANT_DEFAULT_PROVIDER=docker vagrant status + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/README.md b/README.md index 6010ca3..c3eafe7 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,30 @@ MySQL vendors for Debian Ansible role ====================================== -[![Ansible Galaxy](http://img.shields.io/badge/ansible--galaxy-HanXHX.mysql-blue.svg)](https://galaxy.ansible.com/list#/roles/4398) +[![Ansible Galaxy](http://img.shields.io/badge/ansible--galaxy-HanXHX.mysql-blue.svg)](https://galaxy.ansible.com/HanXHX/mysql) [![Build Status](https://travis-ci.org/HanXHX/ansible-mysql.svg?branch=master)](https://travis-ci.org/HanXHX/ansible-mysql) -Install and configure MySQL or MariaDB or Percona Server. Manage replication (master/slave). Create users and databases. +Install and configure MySQL or MariaDB (Galera Cluster) or Percona Server. Manage replication (master/slave). Create users and databases. + +| OS | Vendor | Origin | Managed versions | +| --------------- | ----------------------- | --------- | ------------------------- | +| Debian Jessie | MySQL | Debian | 5.5 / 5.6 | +| Debian Jessie | MariaDB | Debian | 10.0 | +| Debian Jessie | MariaDB | Upstream | 10.0 / 10.1 / 10.2 / 10.3 | +| Debian Jessie | MariaDB Galera Cluster | Upstream | 10.1 / 10.2 | +| Debian Jessie | Percona server | Upstream | 5.5 / 5.6 / 5.7 | +| Debian Stretch | MariaDB | Debian | 10.1 | +| Debian Stretch | MariaDB | Upstream | 10.1 / 10.2 / 10.3 | +| Debian Stretch | MariaDB Galera Cluster | Upstream | 10.1 / 10.2 | + +Notes +----- + +* MySQL 5.6 on Jessie needs backports repository +* MySQL server no longer exists on Debian Stretch +* Percona Server is not available (soon?) on Debian Stretch +* Galera Cluster is experimental +* Due to Vagrant + Docker limitation (private network), replication/galera can't be checked with Travis +* If you need to test this role with Vagrant, you must install hostmanager plugin: `vagrant plugin install vagrant-hostmanager` Requirements ------------ @@ -14,8 +35,7 @@ Role Variables -------------- - `mysql_origin`: origin of the package ("default" or "upstream") -- `mysql_vendor`: "mysql", "mariadb" or "percona" -- `mysql_use_percona_repository`: use percona APT repository (automatic setted to true if you use "percona" as `mysql_vendor`). You need to set "true" on Wheezy if you want to install percona-xtrabackup. +- `mysql_vendor`: "mysql", "mariadb", "mariadb\_galera" (only with MariaDB upstream 10.1) or "percona" ### Configuration @@ -29,7 +49,6 @@ If you need a feature you can't configure, you can use this list. These config w - `mysql_databases`: list... - ### Users Example: @@ -42,14 +61,15 @@ mysql_users: host: '%' ``` -Check "priv" syntax in [mysql_user module documentation](http://docs.ansible.com/mysql_user_module.html) +Check "priv" syntax in [mysql\_user module documentation](http://docs.ansible.com/mysql_user_module.html) ### Packaging -- `mariadb_version`: 5.5 (Debian Wheezy only) or 10.0 -- `mariadb_repository`: MariaDB upstream APT repository (see: [MariaDB repositories tool](http://mariadb.org/mariadb/repositories/)) -- `percona_version`: Percona version 5.5 or 5.6 -- `percona_repository`: Percona upstream APT repository (see: [Percona APT doc](http://www.percona.com/doc/percona-server/5.5/installation/apt_repo.html)) +- `mysql_mariadb_version`: 10.0 / 10.1 / 10.2 +- `mysql_mariadb_repository`: MariaDB upstream APT repository (see: [MariaDB repositories tool](https://downloads.mariadb.org/mariadb/repositories)) +- `mysql_percona_version`: 5.5 / 5.6 / 5.7 +- `mysql_percona_repository`: Percona upstream APT repository (see: [Percona APT doc](http://www.percona.com/doc/percona-server/5.5/installation/apt_repo.html)) +- `mysql_use_percona_apt`: Force using Percona APT repository (useful when you want to use latest version of percona toolkits, xtrabackup... etc) Dependencies ------------ @@ -68,10 +88,19 @@ License GPLv2 +Donation +-------- + +If this code helped you, or if you’ve used them for your projects, feel free to buy me some :beers: + +- Bitcoin: `1BQwhBeszzWbUTyK4aUyq3SRg7rBSHcEQn` +- Ethereum: `63abe6b2648fd892816d87a31e3d9d4365a737b5` +- Litecoin: `LeNDw34zQLX84VvhCGADNvHMEgb5QyFXyD` +- Monero: `45wbf7VdQAZS5EWUrPhen7Wo4hy7Pa7c7ZBdaWQSRowtd3CZ5vpVw5nTPphTuqVQrnYZC72FXDYyfP31uJmfSQ6qRXFy3bQ` + +No crypto-currency? :star: the project is also a way of saying thank you! :sunglasses: + Author Information ------------------ -- You can find many other roles in my GitHub "lab": https://github.com/HanXHX/my-ansible-playbooks -- All issues, pull-request are welcome :) -- Few code come from [geerlingguy](https://github.com/geerlingguy) - +- Twitter: [@hanxhx_](https://twitter.com/hanxhx_) diff --git a/Vagrantfile b/Vagrantfile index 62eda72..06e5a87 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -5,44 +5,86 @@ Vagrant.configure("2") do |config| - vms = [ - ["wheezy-default-mysql-master", "deb/wheezy-amd64", "192.168.200.10", ["wheezy","default","mysql","master"]], - ["wheezy-default-mysql-slave", "deb/wheezy-amd64", "192.168.200.11", ["wheezy","default","mysql","slave"]], - ["wheezy-upstream-mariadb-master", "deb/wheezy-amd64", "192.168.200.12", ["wheezy","upstream","mariadb","master"]], - ["wheezy-upstream-mariadb-slave", "deb/wheezy-amd64", "192.168.200.13", ["wheezy","upstream","mariadb","slave"]], - ["wheezy-upstream-percona-master", "deb/wheezy-amd64", "192.168.200.14", ["wheezy","upstream","percona","master"]], - ["wheezy-upstream-percona-slave", "deb/wheezy-amd64", "192.168.200.15", ["wheezy","upstream","percona","slave"]], - ["jessie-default-mysql-master", "debian/jessie64", "192.168.200.16", ["jessie","default","mysql","master"]], - ["jessie-default-mysql-slave", "debian/jessie64", "192.168.200.17", ["jessie","default","mysql","slave"]], - ["jessie-upstream-mariadb-master", "debian/jessie64", "192.168.200.18", ["jessie","upstream","mariadb","master"]], - ["jessie-upstream-mariadb-slave", "debian/jessie64", "192.168.200.19", ["jessie","upstream","mariadb","slave"]], - ["jessie-upstream-percona-master", "debian/jessie64", "192.168.200.20", ["jessie","upstream","percona","master"]], - ["jessie-upstream-percona-slave", "debian/jessie64", "192.168.200.21", ["jessie","upstream","percona","slave"]], - ["jessie-default-mariadb-master", "debian/jessie64", "192.168.200.22", ["jessie","default","mariadb","master"]], - ["jessie-default-mariadb-slave", "debian/jessie64", "192.168.200.23", ["jessie","default","mariadb","slave"]] - ] + vbox_deb_jessie = 'debian/jessie64' + vbox_deb_stretch = 'debian/stretch64' + dk_deb_jessie = 'hanxhx/vagrant-ansible:debian8' + dk_deb_stretch = 'hanxhx/vagrant-ansible:debian9' - config.vm.provider "virtualbox" do |v| - v.cpus = 1 - v.memory = 256 - end + config.hostmanager.enabled = true + config.hostmanager.manage_host = false + config.hostmanager.manage_guest = true + config.hostmanager.ignore_private_ip = false + config.hostmanager.include_offline = false - vms.each do |vm| - config.vm.define vm[0] do |m| - m.vm.box = vm[1] - m.vm.network "private_network", ip: vm[2] + cases = [ + # Debian Jessie + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: dk_deb_jessie, vars: {mysql_origin: 'default', mysql_vendor: 'mysql' }, groups: ['master'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: nil, vars: {mysql_origin: 'default', mysql_vendor: 'mysql' }, groups: ['slave'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: dk_deb_jessie, vars: {mysql_origin: 'default', mysql_vendor: 'mariadb' }, groups: ['master'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: nil, vars: {mysql_origin: 'default', mysql_vendor: 'mariadb' }, groups: ['slave'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: dk_deb_jessie, vars: {mysql_origin: 'upstream', mysql_vendor: 'mariadb' }, groups: ['master'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: nil, vars: {mysql_origin: 'upstream', mysql_vendor: 'mariadb' }, groups: ['slave'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: dk_deb_jessie, vars: {mysql_origin: 'upstream', mysql_vendor: 'percona' }, groups: ['master'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: nil, vars: {mysql_origin: 'upstream', mysql_vendor: 'percona' }, groups: ['slave'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: dk_deb_jessie, vars: {mysql_origin: 'upstream' }, groups: ['mariadbgalera', '1'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: nil, vars: {mysql_origin: 'upstream' }, groups: ['mariadbgalera', '2'] }, + { os_name: 'jessie', vbox: vbox_deb_jessie, docker: nil, vars: {mysql_origin: 'upstream' }, groups: ['mariadbgalera', '3'] }, + # Debian Stretch + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mysql_origin: 'default', mysql_vendor: 'mysql' }, groups: ['master'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mysql_origin: 'default', mysql_vendor: 'mysql' }, groups: ['slave'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mysql_origin: 'default', mysql_vendor: 'mariadb' }, groups: ['master'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mysql_origin: 'default', mysql_vendor: 'mariadb' }, groups: ['slave'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mysql_origin: 'upstream', mysql_vendor: 'mariadb' }, groups: ['master'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mysql_origin: 'upstream', mysql_vendor: 'mariadb' }, groups: ['slave'] }, +# { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mysql_origin: 'upstream', mysql_vendor: 'percona' }, groups: ['master'] }, +# { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mysql_origin: 'upstream', mysql_vendor: 'percona' }, groups: ['slave'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mysql_origin: 'upstream' }, groups: ['mariadbgalera', '1'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mysql_origin: 'upstream' }, groups: ['mariadbgalera', '2'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mysql_origin: 'upstream' }, groups: ['mariadbgalera', '3'] }, + ] - m.vm.provision "ansible" do |ansible| - ansible.playbook = "tests/test.yml" - ansible.groups = { - vm[3][0] => vm[0], - vm[3][1] => vm[0], - vm[3][2] => vm[0], - vm[3][3] => vm[0], - } - ansible.verbose = 'vv' - ansible.sudo = true - end - end - end + cases.each_with_index do |opts,index| + name = 'docker-' + opts[:os_name] + '-' + opts[:vars].map{|k,v| "#{v}"}.join('-') + '-' + opts[:groups].join('-') + iplsb = 10 + index + ip = '192.168.201.' + iplsb.to_s + next if opts[:docker].nil? + + config.vm.define name do |m| + m.vm.network "private_network", ip: ip + m.vm.provider "docker" do |d| + d.image = opts[:docker] + d.remains_running = true + d.has_ssh = true + end + m.vm.provision "ansible" do |ansible| + ansible.playbook = "tests/test.yml" + ansible.verbose = 'vv' + ansible.sudo = true + ansible.extra_vars = opts[:vars].merge({ is_docker: true }) + ansible.groups = { opts[:groups][0] => name } + end + end + end + + cases.each_with_index do |opts,index| + name = 'vbox-' + opts[:os_name] + '-' + opts[:vars].map{|k,v| "#{v}"}.join('-') + '-' + opts[:groups].join('-') + iplsb = 10 + index + ip = '192.168.200.' + iplsb.to_s + config.vm.define name do |m| + m.vm.hostname = name + m.vm.box = opts[:vbox] + m.vm.network "private_network", ip: ip + m.vm.provider "virtualbox" do |v| + v.cpus = 1 + v.memory = 256 + end + m.vm.provision "ansible" do |ansible| + ansible.playbook = "tests/test.yml" + ansible.verbose = 'vv' + ansible.sudo = true + ansible.extra_vars = opts[:vars].merge({ is_docker: false }) + ansible.groups = { opts[:groups][0] => name } + end + end + end end diff --git a/defaults/main.yml b/defaults/main.yml index 68dd2ee..cbb72b0 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -3,15 +3,19 @@ # ------------------------------------- # Setup # ------------------------------------- -mysql_origin: 'upstream' +mysql_origin: 'default' mysql_vendor: 'mariadb' mysql_root_password: 'change_me_NOW' -mysql_use_percona_repository: false +mysql_notify_restart: true +mysql_upstream_apt_src: false # ------------------------------------- # Configuration # ------------------------------------- +# MySQL configuration template +mysql_config_template: 'etc/mysql/my.cnf.j2' + # MySQL connection settings. mysql_port: "3306" mysql_bind_address: '127.0.0.1' @@ -39,13 +43,12 @@ mysql_query_cache_size: '16M' mysql_wait_timeout: 28800 # Try number of CPU's * 2 for thread_concurrency. -mysql_thread_concurrency: 2 +mysql_thread_concurrency: "{{ ansible_processor_cores * 2 }}" # InnoDB settings. mysql_innodb_file_per_table: '1' -mysql_innodb_buffer_pool_size: "{{ (ansible_memtotal_mb * 0.6) | round | int }}M" -mysql_innodb_additional_mem_pool_size: '20M' # See: http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_additional_mem_pool_size -mysql_innodb_log_file_size: '64M' +mysql_innodb_buffer_pool_size: "{{ (ansible_memtotal_mb * 0.2) | round | int }}M" +mysql_innodb_log_file_size: "{% if ansible_distribution_release == 'jessie' and mysql_vendor == 'mysql' %}5M{% else %}64M{% endif %}" # If this setting changes on a running system, you will break it! http://dev.mysql.com/doc/refman/5.6/en/innodb-data-log-reconfiguration.html mysql_innodb_log_buffer_size: '8M' mysql_innodb_flush_log_at_trx_commit: '1' mysql_innodb_lock_wait_timeout: 50 @@ -62,14 +65,11 @@ mysql_syslog_tag: 'mysql' # Extra configuration # ------------------------------------- # -mysql_extra_configuration: [] +mysql_extra_configuration: {} # Example: #mysql_extra_configuration: -# - group_name: 'mysqld' -# conf: -# - key: 'innodb_awsome_feature' -# value: 1 +# 'innodb_awsome_feature': 1 # ------------------------------------- @@ -80,7 +80,6 @@ mysql_replication_slave: false # This formula don't work with vagrant! All boxes have same default ip! mysql_server_id: "{{ ansible_default_ipv4.address | ipaddr('int') }}" -mysql_replication_user: [] mysql_replication_user: 'repl' mysql_replication_password: 'change_me_NOW' mysql_replication_host: '192.168.0.1' @@ -127,12 +126,23 @@ mysql_users: [] # ------------------------------------- # MariaDB # ------------------------------------- -mariadb_version: '10.0' # (5.5, 10.0) -# See: http://mariadb.org/mariadb/repositories/ -mariadb_repository: "http://ftp.igh.cnrs.fr/pub/mariadb/repo/{{ mariadb_version }}/debian" +mysql_mariadb_version: '10.1' +mysql_mariadb_mirror_domain: "ftp.igh.cnrs.fr" +# See: https://downloads.mariadb.org/mariadb/repositories +mysql_mariadb_repository: "http://{{ mysql_mariadb_mirror_domain }}/pub/mariadb/repo/{{ mysql_mariadb_version }}/debian" +mysql_mariadb_key_server: "keyserver.ubuntu.com" +mysql_mariadb_key_ids: ['0xcbcb082a1bb943db', '0xf1656f24c74cd1d8'] # ------------------------------------- # Percona # ------------------------------------- -percona_version: '5.6' -percona_repository: 'http://repo.percona.com/apt' +mysql_percona_version: '5.6' +mysql_percona_repository: 'http://repo.percona.com/apt' +mysql_use_percona_apt: false +mysql_install_xtrabackup_package: false +mysql_xtrabackup_package: "{{ mysql_default_xtrabackup_package }}" + +# Galera +mysql_galera_resetup: false +mysql_galera_members: [] +mysql_galera_primary_node: 'change_me' # See: https://github.com/ansible/ansible/issues/17453 diff --git a/handlers/main.yml b/handlers/main.yml index 736f653..94bf5f0 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -2,3 +2,4 @@ - name: restart mysql action: service name=mysql state=restarted enabled=yes + when: mysql_notify_restart diff --git a/meta/main.yml b/meta/main.yml index 1619e0b..d996cff 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,18 +1,27 @@ --- galaxy_info: author: Emilien Mantel - description: Install and configure MySQL or MariaDB or Percona server on Debian + description: Install and configure MySQL or MariaDB (Galera Cluster) or Percona server on Debian company: license: GPLv2 - min_ansible_version: 1.8 + min_ansible_version: 2.3 platforms: - name: Debian versions: - - wheezy - jessie - categories: + - stretch + galaxy_tags: - database - database:sql - packaging + - mysql + - mariadb + - percona + - replication + - debian + - galera + - cluster + - jessie + - stretch dependencies: [] diff --git a/tasks/galera/bootstrap.yml b/tasks/galera/bootstrap.yml new file mode 100644 index 0000000..4cd34d1 --- /dev/null +++ b/tasks/galera/bootstrap.yml @@ -0,0 +1,34 @@ +--- +- set_fact: + booboo: "{{ mysql_datadir }}/.ansible_galera_boostrap" + +- name: STAT | Bootstrap mark + stat: path={{ booboo }} + register: s + +- block: + - name: SET_FACT | We must NOT restart after bootstrap! + set_fact: + mysql_notify_restart: false + + - name: SERVICE | Stop MariaDB + service: name=mysql state=stopped + + - name: COMMAND | Bootstrap first node (systemd) + command: galera_new_cluster + when: ansible_service_mgr == 'systemd' + + - name: SERVICE | Bootstrap first node (clean init) + service: + name: mysql + state: started + arguments: --wsrep-new-cluster + register: bootstrap_run + when: ansible_service_mgr != 'systemd' + + when: not s.stat.exists or mysql_galera_resetup + +- name: COMMAND | Create Bootstrap mark + command: "touch {{ booboo }}" + args: + creates: "{{ booboo }}" diff --git a/tasks/galera/main.yml b/tasks/galera/main.yml new file mode 100644 index 0000000..21427a3 --- /dev/null +++ b/tasks/galera/main.yml @@ -0,0 +1,21 @@ +--- + +- name: TEMPLATE | Deploy Galera configuration + template: src=etc/mysql/conf.d/09-galera.cnf.j2 dest=/etc/mysql/conf.d/09-galera.cnf + register: galeraconfig + +- name: INCLUDE | Bootstrap first node + include: 'bootstrap.yml' + when: inventory_hostname == mysql_galera_primary_node + +- name: INCLUDE | Configure other nodes + include: 'nodes.yml' + when: inventory_hostname != mysql_galera_primary_node + +- name: SERVICE | Restart MariaDB if needed + service: name=mysql state=restarted + when: > + ((galeraconfig or (p is defined and p.changed)) and + (bootstrap_run is not defined)) or + ((inventory_hostname != mysql_galera_primary_node) and + (mysql_galera_resetup)) diff --git a/tasks/galera/nodes.yml b/tasks/galera/nodes.yml new file mode 100644 index 0000000..9ff5e98 --- /dev/null +++ b/tasks/galera/nodes.yml @@ -0,0 +1,31 @@ +--- + +- name: COMMAND | GET debian.cnf from primary node + command: cat /etc/mysql/debian.cnf + register: debiancnf + delegate_to: '{{ mysql_galera_primary_node }}' + changed_when: false + +- name: COMMAND | Get current debian.cnf + command: cat /etc/mysql/debian.cnf + register: ondc + changed_when: false + +- block: + + - name: SERVICE | Stop MariaDB + service: name=mysql state=stopped + + - name: COPY | Paste primary node's debian.cnf + copy: > + content={{ debiancnf.stdout }} + dest=/etc/mysql/debian.cnf + mode=0600 + owner=root + group=root + register: paste + + - name: SERVICE | Start MariaDB + service: name=mysql state=started + + when: debiancnf.stdout != ondc.stdout diff --git a/tasks/install/main.yml b/tasks/install/main.yml index 7767df4..68bf356 100644 --- a/tasks/install/main.yml +++ b/tasks/install/main.yml @@ -1,18 +1,21 @@ --- - name: FAIL | If config asked is impossible - fail: msg="config asked is impossible" + fail: msg="config asked is impossible ({{ mysql_origin }} / {{ mysql_vendor }})" when: > not ( (mysql_origin == 'default' and mysql_vendor == 'mysql') or - (mysql_origin == 'default' and mysql_vendor == 'mariadb' and ansible_distribution_major_version > 7) or + (mysql_origin == 'default' and mysql_vendor == 'mariadb') or (mysql_origin == 'upstream' and mysql_vendor == 'mariadb') or + (mysql_origin == 'upstream' and mysql_vendor == 'mariadb_galera') or (mysql_origin == 'upstream' and mysql_vendor == 'percona') ) -- name: APT | Install Percona Xtrabackup - include: percona/apt.yml - when: mysql_use_percona_repository +- name: INCLUDE | Use Percona repository + include: 'percona/apt.yml' + when: > + mysql_use_percona_apt and + not (mysql_origin == 'upstream' and mysql_vendor == 'percona') - name: INCLUDE | Install MySQL from default repo include: 'mysql/default.yml' @@ -20,25 +23,20 @@ - name: INCLUDE | Install MariaDB from Debian repo include: 'mariadb/default.yml' - when: mysql_origin == 'default' and mysql_vendor == 'mariadb' and ansible_distribution_major_version > 7 + when: mysql_origin == 'default' and mysql_vendor == 'mariadb' - name: INCLUDE | Install MariaDB from MariaDB repo include: 'mariadb/upstream.yml' - when: mysql_origin == 'upstream' and mysql_vendor == 'mariadb' + when: mysql_origin == 'upstream' and (mysql_vendor == 'mariadb' or mysql_vendor == 'mariadb_galera') - name: INCLUDE | Install Percona Server from Percona repo include: 'percona/upstream.yml' when: mysql_origin == 'upstream' and mysql_vendor == 'percona' - name: APT | Install few MySQL related tools - apt: pkg={{ item }} state=present - with_items: - - mytop - - percona-toolkit - - python-mysqldb - - mysqltuner - -- name: APT | Install Percona Xtrabackup - apt: pkg=percona-xtrabackup state=present - when: ansible_distribution_major_version > 7 or mysql_use_percona_repository + apt: pkg={{ item }} state=present install_recommends=no + with_items: "{{ mysql_tools }}" +- name: APT | Install percona-xtrabackup if needed + apt: pkg={{ mysql_xtrabackup_package }} + when: mysql_install_xtrabackup_package diff --git a/tasks/install/mariadb/default.yml b/tasks/install/mariadb/default.yml index 94208ca..5056b7e 100644 --- a/tasks/install/mariadb/default.yml +++ b/tasks/install/mariadb/default.yml @@ -16,3 +16,6 @@ - name: APT | Install MariaDB server apt: pkg=mariadb-server state=present +- name: APT | Install Galera + apt: pkg=galera-3 state=present + when: mysql_vendor == 'mariadb_galera' diff --git a/tasks/install/mariadb/upstream.yml b/tasks/install/mariadb/upstream.yml index 2ec3dbb..63e0b54 100644 --- a/tasks/install/mariadb/upstream.yml +++ b/tasks/install/mariadb/upstream.yml @@ -1,14 +1,18 @@ --- -- name: APT | Install MariaDB key - apt_key: keyserver="keyserver.ubuntu.com" id="0xcbcb082a1bb943db" state=present +- name: APT_KEY | Install MariaDB key + apt_key: keyserver="{{ mysql_mariadb_key_server }}" id={{ item }} state=present + with_items: "{{ mysql_mariadb_key_ids }}" -- name: APT | Add MariaDB repository - apt_repository: repo='deb {{ mariadb_repository }} {{ ansible_distribution_release }} main' state=present +- name: TEMPLATE | Deploy APT pinning (prevent upgrades from Debian) + template: src=etc/apt/preferences.d/95-mariadb.j2 dest=/etc/apt/preferences.d/95-mariadb -- name: APT | Add MariaDB (src) repository - apt_repository: repo='deb-src {{ mariadb_repository }} {{ ansible_distribution_release }} main' state=present +- name: APT_REPOSITORY | Add MariaDB repository + apt_repository: repo='deb {{ mysql_mariadb_repository }} {{ ansible_distribution_release }} main' state=present + +- name: APT_REPOSITORY | Add MariaDB (src) repository + apt_repository: repo='deb-src {{ mysql_mariadb_repository }} {{ ansible_distribution_release }} main' state=present + when: mysql_upstream_apt_src - name: INCLUDE | Normal Install include: default.yml - diff --git a/tasks/install/percona/apt.yml b/tasks/install/percona/apt.yml index f1adee7..bd6b98a 100644 --- a/tasks/install/percona/apt.yml +++ b/tasks/install/percona/apt.yml @@ -1,14 +1,15 @@ --- - name: APT_KEY | Install Percona key - apt_key: keyserver="keyserver.ubuntu.com" id="1C4CBDCDCD2EFD2A" state=present + apt_key: keyserver="keyserver.ubuntu.com" id="8507EFA5" state=present - name: TEMPLATE | Deploy APT pinning (prevent upgrades from Debian) - template: src=../../../templates/etc/apt/preferences.d/95-percona.j2 dest=/etc/apt/preferences.d/95-percona + template: src=etc/apt/preferences.d/95-percona.j2 dest=/etc/apt/preferences.d/95-percona - name: APT_REPOSITORY | Add Percona repository - apt_repository: repo='deb {{ percona_repository }} {{ ansible_distribution_release }} main' state=present + apt_repository: repo='deb {{ mysql_percona_repository }} {{ ansible_distribution_release }} main' state=present - name: APT_RESPOSITORY | Add Percona (src) repository - apt_repository: repo='deb-src {{ percona_repository }} {{ ansible_distribution_release }} main' state=present + apt_repository: repo='deb-src {{ mysql_percona_repository }} {{ ansible_distribution_release }} main' state=present + when: mysql_upstream_apt_src diff --git a/tasks/install/percona/upstream.yml b/tasks/install/percona/upstream.yml index 483d83c..155d587 100644 --- a/tasks/install/percona/upstream.yml +++ b/tasks/install/percona/upstream.yml @@ -1,21 +1,16 @@ --- -# We prevent double include - name: INCLUDE | Add percona APT repository include: apt.yml - when: not mysql_use_percona_repository - -- name: SET_FACT | We use percona repository - set_fact: mysql_use_percona_repository=true - name: DEBCONF | Prepare MySQL silent installation (root password) - debconf: name='percona-server-server-{{ percona_version }}' question='percona-server-server/root_password' vtype='password' value='{{ mysql_root_password }}' + debconf: name='percona-server-server-{{ mysql_percona_version }}' question='percona-server-server/root_password' vtype='password' value='{{ mysql_root_password }}' when: not mysql_exists.stat.exists - name: DEBCONF | Prepare MySQL silent installation (root password) - debconf: name='percona-server-server-{{ percona_version }}' question='percona-server-server/root_password_again' vtype='password' value='{{ mysql_root_password }}' + debconf: name='percona-server-server-{{ mysql_percona_version }}' question='percona-server-server/root_password_again' vtype='password' value='{{ mysql_root_password }}' when: not mysql_exists.stat.exists - name: APT | Install Percona - apt: update_cache=yes cache_valid_time=3600 pkg='percona-server-server-{{ percona_version }}' state=present + apt: update_cache=yes cache_valid_time=3600 pkg='percona-server-server-{{ mysql_percona_version }}' state=present diff --git a/tasks/main.yml b/tasks/main.yml index a370275..9c3d16a 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,5 +1,8 @@ --- +- name: INCLUDE_VARS | Related to OS version + include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_release }}.yml" + - name: STAT | Check if mysql exists stat: path=/etc/init.d/mysql register: mysql_exists @@ -9,7 +12,7 @@ include: install/main.yml - name: TEMPLATE | Deploy configuration - template: src=etc/mysql/my.cnf.j2 dest=/etc/mysql/my.cnf + template: "src={{ mysql_config_template }} dest=/etc/mysql/my.cnf" register: config - name: TEMPLATE | Deploy extra configuration @@ -18,11 +21,17 @@ - name: SERVICE | Restart now (prevent bugs) service: name=mysql state=restarted - when: config.changed or extraconfig.changed + when: > + (config.changed or extraconfig.changed) and + not mysql_galera_resetup - name: TEMPLATE Create .my.cnf for root template: src=root/my.cnf dest=/root/.my.cnf owner=root group=root mode=0600 backup=yes +- name: INCLUDE | Galera + include: galera/main.yml + when: mysql_vendor == 'mariadb_galera' + - name: INCLUDE | Replication include: replication/main.yml when: mysql_replication_master or mysql_replication_slave @@ -30,16 +39,18 @@ - name: INCLUDE | Secure install include: 'secure.yml' +- name: SERVICE | Ensure service is started + service: name=mysql state=started + - name: MYSQL_DB | Create databases mysql_db: name={{ item }} state=present - with_items: mysql_databases + with_items: "{{ mysql_databases }}" - name: MYSQL_USER | Manages users... mysql_user: > - name={{ item.name }} - password={{ item.password }} - priv={{ item.priv }} - host={{ item.host | default('localhost') }} + name="{{ item.name }}" + password="{{ item.password }}" + priv="{{ item.priv }}" + host="{{ item.host | default('localhost') }}" state=present - with_items: mysql_users - + with_items: "{{ mysql_users }}" diff --git a/tasks/replication/main.yml b/tasks/replication/main.yml index 1c63d6d..d8bc052 100644 --- a/tasks/replication/main.yml +++ b/tasks/replication/main.yml @@ -1,14 +1,14 @@ --- - name: MYSQL_VARIABLES | Get MySQL vendor - mysql_variables: variable=version_comment + mysql_variables: variable=version register: vc - name: SET_FACT | Server can use GTID set_fact: mysql_gtid=true when: > - ( mysql_vendor == 'mariadb' and vc.msg[0][1] | version_compare('10.0.2', 'ge') ) or - ( vc.msg[0][1] | version_compare('5.6.5', 'ge') ) + ( mysql_vendor == 'mariadb' and vc.msg | version_compare('10.0.2', 'ge') ) or + ( mysql_vendor in ['mysql', 'percona'] and vc.msg | version_compare('5.6.5', 'ge') ) - name: INCLUDE | Replication Master include: master.yml diff --git a/tasks/replication/master.yml b/tasks/replication/master.yml index 85ac2a6..23f4ebe 100644 --- a/tasks/replication/master.yml +++ b/tasks/replication/master.yml @@ -1,5 +1,7 @@ --- - name: TEMPLATE | Deploy master configuration - template: src=../templates/etc/mysql/conf.d/50-master.cnf.j2 dest=/etc/mysql/conf.d/50-master.cnf + template: > + src=etc/mysql/conf.d/50-master.cnf.j2 + dest=/etc/mysql/conf.d/50-master.cnf notify: restart mysql diff --git a/tasks/replication/slave.yml b/tasks/replication/slave.yml index 8be6b51..e3502b4 100644 --- a/tasks/replication/slave.yml +++ b/tasks/replication/slave.yml @@ -5,7 +5,9 @@ when: mysql_slave_readonly - name: TEMPLATE | Deploy slave configuration - template: src=../templates/etc/mysql/conf.d/51-slave.cnf.j2 dest=/etc/mysql/conf.d/51-slave.cnf + template: > + src=etc/mysql/conf.d/51-slave.cnf.j2 + dest=/etc/mysql/conf.d/51-slave.cnf notify: restart mysql - name: MYSQL_REPLICATION | Get slave status @@ -13,13 +15,17 @@ ignore_errors: yes register: slave_status +- name: INCLUDE | Transfert /etc/mysql/debian.cnf from master + include: slave/ssh.yml + when: mysql_slave_replicate_mysqldb or ((slave_status.failed is defined or not slave_status.Is_Slave) and mysql_slave_import_data) + - name: INCLUDE | Import data include: slave/import_data.yml - when: slave_status.failed is defined and mysql_slave_import_data + when: (slave_status.failed is defined or not slave_status.Is_Slave) and mysql_slave_import_data - name: INCLUDE | Configure replication include: slave/replication.yml - when: slave_status.failed is defined or mysql_slave_force_setup + when: (slave_status.failed is defined or not slave_status.Is_Slave) or mysql_slave_force_setup - name: INCLUDE | Transfert /etc/mysql/debian.cnf from master include: slave/debiancnf.yml diff --git a/tasks/replication/slave/import_data.yml b/tasks/replication/slave/import_data.yml index 4013e75..ba25216 100644 --- a/tasks/replication/slave/import_data.yml +++ b/tasks/replication/slave/import_data.yml @@ -1,7 +1,6 @@ --- # Doc: https://www.percona.com/doc/percona-xtrabackup/2.1/howtos/recipes_ibkx_gtid.html - - name: WAIT_FOR | source data (prevent rsync bug) - TODO find another hack wait_for: host={{ mysql_slave_import_from }} port=22 @@ -26,14 +25,15 @@ - name: SET_FACT | related to mysql datadir set_fact: - mysql_mysql_datadir: "{{ datadir.msg[0][1] }}" - mysql_binlog_info: "{{ datadir.msg[0][1] }}/xtrabackup_binlog_info" + mysql_mysql_datadir: "{{ datadir.msg }}" + mysql_binlog_info: "{{ datadir.msg }}/xtrabackup_binlog_info" - name: SERVICE | Stop MySQL before importing data service: name=mysql state=stopped +# TODO: add an "ignore warning" - name: COMMAND | Sync backup to slave - TODO remove vagrant as static user (see why mysql_backup_user is not working) - shell: "sudo -E rsync --rsync-path='sudo rsync' -a -e 'ssh -o StrictHostKeyChecking=no' vagrant@{{ mysql_slave_import_from }}:{{ mysql_backup_dir }}/ {{ mysql_mysql_datadir }}/" + shell: "sudo -E rsync --rsync-path='sudo rsync' -a -e 'ssh -o StrictHostKeyChecking=no' {{ mysql_backup_user }}@{{ mysql_slave_import_from }}:{{ mysql_backup_dir }}/ {{ mysql_mysql_datadir }}/" become: no - name: FILE | Re-apply owner diff --git a/tasks/replication/slave/replication.yml b/tasks/replication/slave/replication.yml index d8d3b8a..3cf14d7 100644 --- a/tasks/replication/slave/replication.yml +++ b/tasks/replication/slave/replication.yml @@ -20,4 +20,3 @@ - name: MYSQL_REPLICATION | Start slave mysql_replication: mode=startslave - diff --git a/tasks/replication/slave/ssh.yml b/tasks/replication/slave/ssh.yml new file mode 100644 index 0000000..c9e5ceb --- /dev/null +++ b/tasks/replication/slave/ssh.yml @@ -0,0 +1,19 @@ +--- + +- name: SHELL | Create SSH key if needed on slave + shell: "ssh-keygen -b 2048 -t rsa -f {{ ansible_env.HOME }}/.ssh/id_rsa -q -N ''" + args: + creates: "{{ ansible_env.HOME }}/.ssh/id_rsa" + +- name: COMMAND | Get pub key + command: cat {{ ansible_env.HOME }}/.ssh/id_rsa.pub + register: pub_key + changed_when: false + +- name: AUTHORIZED_KEY | Auth slave to backup host + authorized_key: + user: "{{ mysql_backup_user }}" + state: present + key: "{{ pub_key.stdout }}" + delegate_to: "{{ mysql_slave_import_from }}" + become: yes diff --git a/templates/etc/apt/preferences.d/95-mariadb.j2 b/templates/etc/apt/preferences.d/95-mariadb.j2 new file mode 100644 index 0000000..740bae1 --- /dev/null +++ b/templates/etc/apt/preferences.d/95-mariadb.j2 @@ -0,0 +1,6 @@ +# {{ ansible_managed }} + +Explanation: Prevent Debian upgrades on mariadb packages +Package: * +Pin: origin {{ mysql_mariadb_mirror_domain }} +Pin-Priority: 1000 diff --git a/templates/etc/mysql/conf.d/09-galera.cnf.j2 b/templates/etc/mysql/conf.d/09-galera.cnf.j2 new file mode 100644 index 0000000..3ec5274 --- /dev/null +++ b/templates/etc/mysql/conf.d/09-galera.cnf.j2 @@ -0,0 +1,31 @@ +# +# {{ ansible_managed }} +# + +[mysqld] + +# -------------------- +# Galera config +# -------------------- + +# Global +wsrep_on=ON +wsrep_provider=/usr/lib/galera/libgalera_smm.so +wsrep_cluster_address=gcomm://{{ mysql_galera_members | join(",") }} +# TODO: https://mariadb.com/kb/en/mariadb/galera-cluster-system-variables/#wsrep_sst_method +wsrep_sst_method=rsync +# TODO: wsrep_cluster_name="my_wsrep_cluster" + +# Node Configuration +wsrep_node_address="{{ mysql_wsrep_node_address | default(ansible_eth0.ipv4.address) }}" +wsrep_node_name="{{ mysql_wsrep_node_name | default(ansible_fqdn) }}" + + +# -------------------- +# Deps +# -------------------- +binlog_format=ROW +default_storage_engine=InnoDB +innodb_autoinc_lock_mode=2 +innodb_doublewrite=1 +query_cache_size=0 diff --git a/templates/etc/mysql/conf.d/10-extra.cnf.j2 b/templates/etc/mysql/conf.d/10-extra.cnf.j2 index b37ab9e..55f521b 100644 --- a/templates/etc/mysql/conf.d/10-extra.cnf.j2 +++ b/templates/etc/mysql/conf.d/10-extra.cnf.j2 @@ -2,16 +2,13 @@ # {{ ansible_managed }} # ------------------------------------------- -{% for i in mysql_extra_configuration %} -[{{ i.group_name }}] -{% for c in i.conf %} -{% if c.value is defined %} -{{ c.key }} = {{ c.value }} +[mysqld] +{% for key, value in mysql_extra_configuration.items() %} +{% if value is defined or value is not none %} +{{ key }} = {{ value }} {% else %} -{{ c.key }} +{{ key }} {% endif %} {% endfor %} -{% endfor %} - ; vim: set ft=dosini : diff --git a/templates/etc/mysql/my.cnf.j2 b/templates/etc/mysql/my.cnf.j2 index 11d9c7e..a7e21d5 100644 --- a/templates/etc/mysql/my.cnf.j2 +++ b/templates/etc/mysql/my.cnf.j2 @@ -12,28 +12,28 @@ bind-address = {{ mysql_bind_address }} datadir = {{ mysql_datadir }} socket = {{ mysql_socket }} -# TODO: FIX later +{# TODO: FIX later #} # Logging configuration. -#{% if mysql_log_error == 'syslog' or mysql_log == 'syslog' %} -#syslog -#syslog-tag = {{ mysql_syslog_tag }} -#{% else %} -#{% if mysql_log %} -#log = {{ mysql_log }} -#{% endif %} -#log-error = {{ mysql_log_error }} -#{% endif %} +{% if mysql_log_error == 'syslog' or mysql_log == 'syslog' %} +syslog +syslog-tag = {{ mysql_syslog_tag }} +{% else %} +{% if mysql_log %} +log = {{ mysql_log }} +{% endif %} +log-error = {{ mysql_log_error }} +{% endif %} {% if mysql_slow_query_log_enabled %} # Slow query log configuration. +{% if mysql_vendor not in ['mariadb', 'mariadbgalera'] or mysql_mariadb_version | version_compare('10.0', '<') %} log_slow_queries = 1 +{% endif %} slow_query_log = 1 slow_query_log_file = {{ mysql_slow_query_log_file }} long_query_time = {{ mysql_slow_query_time }} {% endif %} - - # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links = 0 @@ -63,14 +63,13 @@ thread_concurrency = {{ mysql_thread_concurrency }} # InnoDB settings. innodb_file_per_table = {{ mysql_innodb_file_per_table }} innodb_buffer_pool_size = {{ mysql_innodb_buffer_pool_size }} -{% if mysql_innodb_additional_mem_pool_size is defined %} -innodb_additional_mem_pool_size = {{ mysql_innodb_additional_mem_pool_size }} -{% endif %} -# It craches after install (mysql 5.5)... TODO FIX -> http://dev.mysql.com/doc/refman/5.6/en/innodb-data-log-reconfiguration.html -#innodb_log_file_size = {{ mysql_innodb_log_file_size }} -#innodb_log_buffer_size = {{ mysql_innodb_log_buffer_size }} +innodb_log_buffer_size = {{ mysql_innodb_log_buffer_size }} innodb_flush_log_at_trx_commit = {{ mysql_innodb_flush_log_at_trx_commit }} innodb_lock_wait_timeout = {{ mysql_innodb_lock_wait_timeout }} +{# If this setting changes on a running system, you will break it! #} +{# See how tho change it here: http://dev.mysql.com/doc/refman/5.6/en/innodb-data-log-reconfiguration.html #} +{# TODO FIX -> Maybe detect a change and fail, just to be safe? #} +innodb_log_file_size = {{ mysql_innodb_log_file_size }} [mysqldump] quick diff --git a/templates/root/my.cnf b/templates/root/my.cnf index dae1d87..6052e60 100644 --- a/templates/root/my.cnf +++ b/templates/root/my.cnf @@ -4,5 +4,4 @@ [client] user=root -password={{ mysql_root_password }} - +password="{{ mysql_root_password }}" diff --git a/tests/README.md b/tests/README.md index 23d30ad..196c231 100644 --- a/tests/README.md +++ b/tests/README.md @@ -4,10 +4,8 @@ About tests IMPORTANT --------- -- DO NOT `vagrant up`! My Vagrantfile provides 14 VMs (256MB each)... -- Each slave communicate to his master. You can't mix jessie and wheezy or mysql and mariadb. -- This tests uses my [MySQL role](https://github.com/HanXHX/ansible-mysql). - +- DO NOT `vagrant up`! My Vagrantfile provides many VMs... +- Each slave communicate to his master. You can't mix mysql and mariadb. Tests ----- @@ -20,30 +18,6 @@ Wait master fully installed before run slave. Example: ``` -sudo ansible-galaxy install HanXHX.mysql vagrant up jessie-upstream-mariadb-master vagrant up jessie-upstream-mariadb-slave ``` - -Supported platforms -------------------- - -- Debian Wheezy -- Debian Jessie - -Supported MySQL vendors ------------------------ - -- MariaDB 10.0 (from Debian Jessie or MariaDB repository) -- MySQL 5.5 (from Debian repositories) -- Percona Server 5.6 (from Percona Repository) - -About MySQL 5.6 ---------------- - -You can get MySQL 5.6 for Debian with [Dotdeb](https://www.dotdeb.org) with my [Dotdeb role](https://github.com/HanXHX/ansible-debian-dotdeb). I give no support with this version (pull-request accepted). It can work but without GTID. - -About MariaDB 10.1 ------------------- - -When the application is considered stable, I'll support this version. diff --git a/tests/debian-jessie.Dockerfile b/tests/debian-jessie.Dockerfile deleted file mode 100644 index cd78566..0000000 --- a/tests/debian-jessie.Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM williamyeh/ansible:debian8-onbuild - -RUN apt-get update -CMD ["sh", "tests/test.sh"] diff --git a/tests/debian-wheezy.Dockerfile b/tests/debian-wheezy.Dockerfile deleted file mode 100644 index bc45db9..0000000 --- a/tests/debian-wheezy.Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM williamyeh/ansible:debian7-onbuild - -RUN apt-get update -CMD ["sh", "tests/test.sh"] diff --git a/tests/gen.pl b/tests/gen.pl deleted file mode 100755 index 5de9ffc..0000000 --- a/tests/gen.pl +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/perl - -# -# This script generates ansible test config for Vagrant -# - -use strict; -use warnings; -use Socket; - -my @a = ( - "wheezy-default-mysql-master", - "wheezy-default-mysql-slave", - "wheezy-upstream-mariadb-master", - "wheezy-upstream-mariadb-slave", - "wheezy-upstream-percona-master", - "wheezy-upstream-percona-slave", - "jessie-default-mysql-master", - "jessie-default-mysql-slave", - "jessie-upstream-mariadb-master", - "jessie-upstream-mariadb-slave", - "jessie-upstream-percona-master", - "jessie-upstream-percona-slave", - "jessie-default-mariadb-master", - "jessie-default-mariadb-slave", -); - -my $start_ip = '192.168.200.10'; -my $iip = ip2long($start_ip); -my $tmp_ip = 0; - -foreach my $n (@a) -{ - my @data = split(/-/, $n); - printf( - '["%s", "deb/%s-amd64", "%s", [%s]],' . "\n", - $n, - $data[0], - long2ip($iip), - join(',', map { sprintf('"%s"', $_) } @data) - ); - - if($data[-1] eq 'slave') - { - open(FILE, '>', "host_vars/$n"); - printf FILE (qq/his_master: '%s'\n/, $tmp_ip); - close(FILE); - } - - open(FILE, '>', "group_vars/" . $data[2]); - printf FILE (qq/mysql_vendor: '%s'\n/, $data[2]); - close(FILE); - - $tmp_ip = long2ip($iip); - $iip++; -} - -sub ip2long { - return unpack("l*", pack("l*", unpack("N*", inet_aton(shift)))); -} - -sub long2ip { - return inet_ntoa(pack("N*", shift)); -} diff --git a/tests/group_vars/all b/tests/group_vars/all index bfb0487..a6ea88c 100644 --- a/tests/group_vars/all +++ b/tests/group_vars/all @@ -1 +1,5 @@ -mysql_use_percona_repository: true +mysql_bind_address: '0.0.0.0' +mysql_extra_configuration: + innodb_commit_concurrency: 0 +mysql_use_percona_apt: true +mysql_install_xtrabackup_package: true diff --git a/tests/group_vars/default b/tests/group_vars/default deleted file mode 100644 index 0ad8c51..0000000 --- a/tests/group_vars/default +++ /dev/null @@ -1 +0,0 @@ -mysql_origin: 'default' diff --git a/tests/group_vars/mariadb b/tests/group_vars/mariadb deleted file mode 100644 index c4bf047..0000000 --- a/tests/group_vars/mariadb +++ /dev/null @@ -1 +0,0 @@ -mysql_vendor: 'mariadb' diff --git a/tests/group_vars/mariadbgalera b/tests/group_vars/mariadbgalera new file mode 100644 index 0000000..0a6e9e8 --- /dev/null +++ b/tests/group_vars/mariadbgalera @@ -0,0 +1,5 @@ +mysql_vendor: 'mariadb_galera' +mysql_galera_members: + - '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-mariadbgalera-1' + - '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-mariadbgalera-2' + - '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-mariadbgalera-3' diff --git a/tests/group_vars/master b/tests/group_vars/master index 0294770..b1b48f6 100644 --- a/tests/group_vars/master +++ b/tests/group_vars/master @@ -1,6 +1,3 @@ -# Master must listen for replication -mysql_bind_address: '0.0.0.0' - # Master durability mysql_sync_binlog: '1' mysql_innodb_flush_log_at_trx_commit: '1' @@ -12,7 +9,7 @@ mysql_databases: mysql_users: - name: 'replication' password: '1a2b3c' - priv: '*.*:"REPLICATION SLAVE"' + priv: '*.*:REPLICATION SLAVE' host: '%' mysql_replication_master: true mysql_replication_slave: false diff --git a/tests/group_vars/percona b/tests/group_vars/percona deleted file mode 100644 index a8d9776..0000000 --- a/tests/group_vars/percona +++ /dev/null @@ -1 +0,0 @@ -mysql_vendor: 'percona' diff --git a/tests/group_vars/slave b/tests/group_vars/slave index 1af3ad2..b1349bf 100644 --- a/tests/group_vars/slave +++ b/tests/group_vars/slave @@ -2,7 +2,6 @@ mysql_replication_master: false mysql_replication_slave: true mysql_replication_user: 'replication' mysql_replication_password: '1a2b3c' -mysql_replication_host: '{{ his_master }}' mysql_server_id: 2 mysql_slave_ignore_db: ['norepl'] diff --git a/tests/group_vars/upstream b/tests/group_vars/upstream deleted file mode 100644 index 5b92d9b..0000000 --- a/tests/group_vars/upstream +++ /dev/null @@ -1 +0,0 @@ -mysql_origin: 'upstream' diff --git a/tests/host_vars/jessie-default-mariadb-slave b/tests/host_vars/jessie-default-mariadb-slave deleted file mode 100644 index fab920a..0000000 --- a/tests/host_vars/jessie-default-mariadb-slave +++ /dev/null @@ -1 +0,0 @@ -his_master: '192.168.200.22' diff --git a/tests/host_vars/jessie-default-mysql-slave b/tests/host_vars/jessie-default-mysql-slave deleted file mode 100644 index 812a255..0000000 --- a/tests/host_vars/jessie-default-mysql-slave +++ /dev/null @@ -1 +0,0 @@ -his_master: '192.168.200.16' diff --git a/tests/host_vars/jessie-upstream-mariadb-slave b/tests/host_vars/jessie-upstream-mariadb-slave deleted file mode 100644 index 0dc0978..0000000 --- a/tests/host_vars/jessie-upstream-mariadb-slave +++ /dev/null @@ -1 +0,0 @@ -his_master: '192.168.200.18' diff --git a/tests/host_vars/jessie-upstream-percona-slave b/tests/host_vars/jessie-upstream-percona-slave deleted file mode 100644 index db8abd8..0000000 --- a/tests/host_vars/jessie-upstream-percona-slave +++ /dev/null @@ -1 +0,0 @@ -his_master: '192.168.200.20' diff --git a/tests/host_vars/wheezy-default-mysql-slave b/tests/host_vars/wheezy-default-mysql-slave deleted file mode 100644 index b9a7abf..0000000 --- a/tests/host_vars/wheezy-default-mysql-slave +++ /dev/null @@ -1 +0,0 @@ -his_master: '192.168.200.10' diff --git a/tests/host_vars/wheezy-upstream-mariadb-slave b/tests/host_vars/wheezy-upstream-mariadb-slave deleted file mode 100644 index 5a0ff93..0000000 --- a/tests/host_vars/wheezy-upstream-mariadb-slave +++ /dev/null @@ -1 +0,0 @@ -his_master: '192.168.200.12' diff --git a/tests/host_vars/wheezy-upstream-percona-slave b/tests/host_vars/wheezy-upstream-percona-slave deleted file mode 100644 index ed31632..0000000 --- a/tests/host_vars/wheezy-upstream-percona-slave +++ /dev/null @@ -1 +0,0 @@ -his_master: '192.168.200.14' diff --git a/tests/test.sh b/tests/test.sh deleted file mode 100644 index e14025a..0000000 --- a/tests/test.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# Thanks to https://servercheck.in/blog/testing-ansible-roles-travis-ci-github - -DIR=$( dirname $0 ) -INVENTORY_FILE="$DIR/inventory" -PLAYBOOK="$DIR/test.yml" - -set -ev - -# Check syntax -ansible-playbook -i $INVENTORY_FILE -c local --syntax-check -vv $PLAYBOOK - -# Check role -ansible-playbook -i $INVENTORY_FILE -c local --sudo -vv $PLAYBOOK - -# Check indempotence -ansible-playbook -i $INVENTORY_FILE -c local --sudo -vv $PLAYBOOK \ -| grep -q 'changed=0.*failed=0' \ -&& (echo 'Idempotence test: pass' && exit 0) \ -|| (echo 'Idempotence test: fail' && exit 1) diff --git a/tests/test.yml b/tests/test.yml index 81677b6..bfa7d4d 100644 --- a/tests/test.yml +++ b/tests/test.yml @@ -1,19 +1,13 @@ --- - hosts: all - pre_tasks: - - local_action: shell ssh-add $HOME/.vagrant.d/insecure_private_key - become: no - changed_when: false tasks: - apt: pkg={{ item }} state=present update_cache=yes cache_valid_time=3600 with_items: + - ca-certificates + - curl - strace - vim - - get_url: > - url=https://raw.githubusercontent.com/HanXHX/ansible-debian-bootstrap/master/files/bashrc - dest=/root/.bashrc - force=yes - hosts: master roles: @@ -26,14 +20,40 @@ when: c.changed - hosts: slave + pre_tasks: + - name: SHELL | Get master IP + shell: getent hosts {{ ansible_hostname | replace ('slave', 'master') }} | cut -d ' ' -f 1 + register: ip + changed_when: false + - set_fact: + # MySQL don't read /etc/hosts (from vagrant host plugin) + mysql_replication_host: "{{ ip.stdout }}" + # Need this to use vagrant 'delegate_to' + mysql_slave_import_from: "{{ ansible_hostname | replace ('slave', 'master') }}" roles: - ../../ tasks: - copy: src=import2.sql dest=/tmp/import2.sql - delegate_to: "{{ his_master }}" + delegate_to: "{{ mysql_slave_import_from }}" register: c - mysql_db: name={{ item }} state=import target=/tmp/import2.sql with_items: ['testrepl', 'norepl'] - delegate_to: "{{ his_master }}" + delegate_to: "{{ mysql_slave_import_from }}" when: c.changed + - mysql_replication: mode=getslave + register: slave + - fail: msg="Slave issue" + when: slave.Slave_IO_Running != 'Yes' or slave.Slave_SQL_Running != 'Yes' + +- hosts: mariadbgalera + vars: + mysql_galera_primary_node: '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-mariadbgalera-1' + mysql_wsrep_node_address: "{{ ansible_all_ipv4_addresses[0] }}" + mysql_mariadb_version: '10.1' + pre_tasks: + - set_fact: + mysql_wsrep_node_address: "{{ ansible_eth1.ipv4.address }}" + when: not is_docker + roles: + - ../../ diff --git a/tests/travis.sh b/tests/travis.sh new file mode 100644 index 0000000..36f9020 --- /dev/null +++ b/tests/travis.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# Thanks to https://servercheck.in/blog/testing-ansible-roles-travis-ci-github + +DIR=$( dirname $0 ) +INVENTORY_FILE="localhost," +PLAYBOOK="$DIR/travis.yml" + +set -ev + +# Check syntax +ansible-playbook -i $INVENTORY_FILE -c local --syntax-check -vv $PLAYBOOK + +# Check role +ansible-playbook -i $INVENTORY_FILE -c local -e "{ mysql_vendor: $VENDOR, mysql_origin: $ORIGIN }" --sudo -vv $PLAYBOOK + +# Check indempotence +ansible-playbook -i $INVENTORY_FILE -c local -e "{ mysql_vendor: $VENDOR, mysql_origin: $ORIGIN }" --sudo -vv $PLAYBOOK > idempot.txt +grep -q 'changed=0.*failed=0' idempot.txt \ +&& (echo 'Idempotence test: pass' && exit 0) \ +|| (echo 'Idempotence test: FAIL' && cat idempot.txt && exit 1) diff --git a/tests/travis.yml b/tests/travis.yml new file mode 100644 index 0000000..934fe89 --- /dev/null +++ b/tests/travis.yml @@ -0,0 +1,15 @@ +--- + +- hosts: all + vars: + mysql_replication_master: true + mysql_bind_address: '{{ ansible_eth0.ipv4.address }}' + mysql_galera_members: + - '{{ ansible_eth0.ipv4.address }}' + mysql_galera_primary_node: 'localhost' + roles: + - ../../ + post_tasks: + - name: TEST | SHELL | Test mysql + shell: mysql -e "SHOW DATABASES;" + changed_when: false diff --git a/vars/Debian-jessie.yml b/vars/Debian-jessie.yml new file mode 100644 index 0000000..8f67125 --- /dev/null +++ b/vars/Debian-jessie.yml @@ -0,0 +1,7 @@ +mysql_tools: + - mytop + - percona-toolkit + - python-mysqldb + - mysqltuner + +mysql_default_xtrabackup_package: 'percona-xtrabackup' diff --git a/vars/Debian-stretch.yml b/vars/Debian-stretch.yml new file mode 100644 index 0000000..a56b5a0 --- /dev/null +++ b/vars/Debian-stretch.yml @@ -0,0 +1,6 @@ +mysql_tools: + - percona-toolkit + - python-mysqldb + - mysqltuner + +mysql_default_xtrabackup_package: 'percona-xtrabackup-24' diff --git a/vars/main.yml b/vars/main.yml deleted file mode 100644 index a4ce68b..0000000 --- a/vars/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -default_mysql: true -mariadb_mariadb: true -percona_percona: true - -percona_available_versions: - - '5.5' - - '5.6'