diff --git a/.github/workflows/molecule.yml b/.github/workflows/molecule.yml index 96ec0fe..fba48a5 100644 --- a/.github/workflows/molecule.yml +++ b/.github/workflows/molecule.yml @@ -9,7 +9,7 @@ on: jobs: molecule-distrib-pkg: - name: Molecule + name: Default runs-on: ubuntu-latest strategy: fail-fast: false @@ -21,6 +21,12 @@ jobs: - debian-10 - debian-11 - debian-sid + - fedora-36 + - fedora-37 + - almalinux-8 + - almalinux-9 + - rockylinux-8 + - rockylinux-9 playbook: - converge.yml steps: @@ -45,7 +51,7 @@ jobs: MOLECULE_PLAYBOOK: ${{ matrix.playbook }} molecule-mdbf-pkg: - name: Molecule (MDBF) + name: MDBF runs-on: ubuntu-latest strategy: fail-fast: false @@ -57,8 +63,14 @@ jobs: - debian-10 - debian-11 - debian-sid + - fedora-36 + # - fedora-37 + - almalinux-8 + - almalinux-9 + - rockylinux-8 + - rockylinux-9 playbook: - - converge-mdbf.yml + - mdbf.yml mariadb-version: - "10.3" - "10.4" @@ -89,18 +101,20 @@ jobs: mariadb-version: 10.3 - distro: debian-sid mariadb-version: 10.4 - - distro: debian-sid + - distro: fedora-36 + mariadb-version: 10.3 + - distro: fedora-36 + mariadb-version: 10.4 + - distro: fedora-36 mariadb-version: 10.5 - - distro: debian-sid - mariadb-version: 10.6 - - distro: debian-sid - mariadb-version: 10.7 - - distro: debian-sid - mariadb-version: 10.8 - - distro: debian-sid - mariadb-version: 10.9 - - distro: debian-sid - mariadb-version: 10.10 + - distro: almalinux-9 + mariadb-version: 10.3 + - distro: almalinux-9 + mariadb-version: 10.4 + - distro: rockylinux-9 + mariadb-version: 10.3 + - distro: rockylinux-9 + mariadb-version: 10.4 steps: - uses: actions/checkout@v3 diff --git a/README.md b/README.md index 863e8ba..122d5ca 100644 --- a/README.md +++ b/README.md @@ -71,21 +71,24 @@ Foundation package and it should be easy to change them all (see #### Basic settings +`default value depends on OS` means that the value is overrided at OS level, see +[`vars`](./vars). + ```yaml -mariadb_config_file: /etc/mysql/mariadb.cnf -mariadb_datadir: /var/lib/mysql +mariadb_config_file: "default value depends on OS" +mariadb_data_dir: "default value depends on OS" mariadb_port: 3306 mariadb_bind_address: 127.0.0.1 -mariadb_unix_socket: /run/mysqld/mysqld.sock +mariadb_unix_socket: "default value depends on OS" ``` ```yaml mariadb_basic_settings_raw: | user = mysql - pid-file = /run/mysqld/mysqld.pid + pid-file = {{ mariadb_pid_file }} socket = {{ mariadb_unix_socket }} basedir = /usr - datadir = {{ mariadb_datadir }} + datadir = {{ mariadb_data_dir }} tmpdir = /tmp lc-messages-dir = /usr/share/mysql lc_messages = en_US @@ -120,7 +123,7 @@ mariadb_query_cache_raw: | ```yaml mariadb_logging_raw: | - log_error = /var/log/mysql/error.log + log_error = "default value depends on OS" ``` #### Character sets diff --git a/defaults/main.yml b/defaults/main.yml index 87c92bb..76c56f3 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,9 +1,12 @@ --- +# Python interpreter needs to be specified (pb on Fedora 37 that has python +# 3.11) see: https://github.com/ansible/containmint/issues/9 +ansible_python_interpreter: /usr/bin/python3 # Configure the following to use official MariaDB repository # see: https://downloads.mariadb.org/mariadb/repositories mariadb_use_official_repo: false mariadb_use_official_repo_url: https://deb.mariadb.org -mariadb_use_official_repo_version: 10.5 +mariadb_use_official_repo_version: 10.6 mariadb_enabled_on_startup: true # The following is set to true by default but you may consider setting it to @@ -14,18 +17,21 @@ mariadb_can_restart: true mariadb_overwrite_global_config_file: true # MariaDB configuration file -mariadb_config_file: /etc/mysql/mariadb.cnf +mariadb_user: "default value depends on OS" +mariadb_config_file: "default value depends on OS" # Basic settings -mariadb_datadir: /var/lib/mysql +mariadb_data_dir: "default value depends on OS" mariadb_port: 3306 mariadb_bind_address: 127.0.0.1 -mariadb_unix_socket: /run/mysqld/mysqld.sock +mariadb_pid_file: "default value depends on OS" +mariadb_unix_socket: "default value depends on OS" +mariadb_log_error_file: "default value depends on OS" mariadb_basic_settings_raw: | - user = mysql - pid-file = /run/mysqld/mysqld.pid + user = {{ mariadb_user }} + pid-file = {{ mariadb_pid_file }} socket = {{ mariadb_unix_socket }} basedir = /usr - datadir = {{ mariadb_datadir }} + datadir = {{ mariadb_data_dir }} tmpdir = /tmp lc-messages-dir = /usr/share/mysql lc_messages = en_US @@ -52,7 +58,7 @@ mariadb_query_cache_raw: | # Logging mariadb_logging_raw: | - log_error = /var/log/mysql/error.log + log_error = {{ mariadb_log_error_file }} # Character sets mariadb_character_sets_raw: | diff --git a/molecule/default/converge-mdbf.yml b/molecule/default/mdbf.yml similarity index 100% rename from molecule/default/converge-mdbf.yml rename to molecule/default/mdbf.yml diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index d5b8b54..481dd63 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -16,4 +16,10 @@ provisioner: playbooks: converge: ${MOLECULE_PLAYBOOK:-converge.yml} verifier: - name: testinfra + name: ansible +scenario: + test_sequence: + - create + - converge + - idempotence + - verify diff --git a/molecule/default/tests/test_default.py b/molecule/default/tests/test_default.py deleted file mode 100644 index acb3f8f..0000000 --- a/molecule/default/tests/test_default.py +++ /dev/null @@ -1,70 +0,0 @@ -import os - -# pylint: disable=import-error -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') - - -def test_passwd_file(host): - passwd = host.file("/etc/passwd") - assert passwd.contains("mysql") - assert passwd.user == "root" - assert passwd.group == "root" - - -def test_mariadb_is_installed(host): - package = host.package("mariadb-server") - assert package.is_installed - - -def test_ensure_mariadb_is_listening_on_requiered_port(host): - assert host.socket("tcp://0.0.0.0:3306").is_listening - - -def test_mariadb_enabled_and_running(host): - assert host.service("mariadb").is_running - assert host.service("mariadb").is_enabled - - -def test_ensure_custom_config_is_applied(host): - config = host.file("/etc/mysql/mariadb.cnf") - assert config.contains("datadir") - assert config.user == "root" - assert config.group == "root" - assert config.mode == 0o644 - - -def test_ensure_innodb_is_enabled(host): - assert host.run("mariadb -Bse 'SHOW ENGINES' |\ - grep -qE '^InnoDB.DEFAULT.*YES.YES.YES$'").rc == 0 - - -def test_ensure_system_db_exist(host): - assert host.run("mariadb -Bse 'SHOW DATABASES' |\ - grep -q '^mysql$'").rc == 0 - assert host.run("mariadb -Bse 'SHOW DATABASES' |\ - grep -q '^information_schema$'").rc == 0 - assert host.run("mariadb -Bse 'SHOW DATABASES' |\ - grep -q '^performance_schema$'").rc == 0 - - -def test_ensure_test_db_exist(host): - assert host.run("mariadb -Bse 'SHOW DATABASES' |\ - grep -q '^db1'").rc == 0 - assert host.run("mariadb -Bse 'SHOW DATABASES' |\ - grep -q '^db2'").rc == 0 - - -def test_some_sql_queries(host): - assert host.run("mariadb -e 'CREATE DATABASE db'").rc == 0 - assert host.run("mariadb -e 'CREATE TABLE\ - db.t_innodb(a1 SERIAL, c1 CHAR(8)) ENGINE=InnoDB;\ - INSERT INTO db.t_innodb VALUES (1,\"foo\"),(2,\"bar\")'").rc == 0 - assert host.run("mariadb -e 'CREATE FUNCTION db.f()\ - RETURNS INT DETERMINISTIC RETURN 1'").rc == 0 - assert host.run("mariadb -e 'SHOW TABLES IN db'").rc == 0 - assert host.run("mariadb -e 'SELECT * FROM db.t_innodb;\ - INSERT INTO db.t_innodb VALUES (3,\"foo\"),(4,\"bar\")'").rc == 0 - assert host.run("mariadb -e 'SELECT db.f()'").rc == 0 diff --git a/molecule/default/vars/Debian.yml b/molecule/default/vars/Debian.yml new file mode 120000 index 0000000..c6ef0b7 --- /dev/null +++ b/molecule/default/vars/Debian.yml @@ -0,0 +1 @@ +../../../vars/Debian.yml \ No newline at end of file diff --git a/molecule/default/vars/RedHat.yml b/molecule/default/vars/RedHat.yml new file mode 120000 index 0000000..98913c1 --- /dev/null +++ b/molecule/default/vars/RedHat.yml @@ -0,0 +1 @@ +../../../vars/RedHat.yml \ No newline at end of file diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml new file mode 100644 index 0000000..58f5aad --- /dev/null +++ b/molecule/default/verify.yml @@ -0,0 +1,116 @@ +--- +- name: Verify + hosts: all + gather_facts: true + + tasks: + - name: Load OS-specific vars + ansible.builtin.include_vars: "{{ lookup('first_found', params) }}" + vars: + params: + files: + - "{{ ansible_distribution }}.yml" + - "{{ ansible_os_family }}.yml" + paths: + - "vars" + + - name: Gather package facts + ansible.builtin.package_facts: + manager: auto + + - name: Verify Packages + ansible.builtin.assert: + that: "'mariadb-server' in ansible_facts.packages|lower" + + - name: Register {{ mariadb_config_file }} + ansible.builtin.stat: + path: "{{ mariadb_config_file }}" + register: conf + + - name: Check {{ mariadb_config_file }} + ansible.builtin.assert: + that: + - conf.stat.exists is true + - conf.stat.pw_name == 'root' + - conf.stat.gr_name == 'root' + + - name: Register {{ mariadb_data_dir }} + ansible.builtin.stat: + path: "{{ mariadb_data_dir }}" + register: datadir + + - name: Check {{ mariadb_data_dir }} + ansible.builtin.assert: + that: + - datadir.stat.isdir is true + - datadir.stat.pw_name == "{{ mariadb_user }}" + - datadir.stat.gr_name == "{{ mariadb_user }}" + + - name: Register {{ mariadb_log_dir }} + ansible.builtin.stat: + path: "{{ mariadb_log_dir }}" + register: logdir + + - name: Check {{ mariadb_log_dir }} + ansible.builtin.assert: + that: + - logdir.stat.isdir is true + - logdir.stat.pw_name == "{{ mariadb_user }}" + - logdir.stat.gr_name == "{{ mariadb_user }}" + + - name: Get mariadb service status + ansible.builtin.systemd: + name: "mariadb" + register: mariadb_service + + - name: Check that mariadb service is active + ansible.builtin.assert: + that: + - mariadb_service.status.ActiveState == 'active' + + - name: Check that 127.0.0.1:3306 is listening + ansible.builtin.wait_for: + port: 3306 + timeout: 2 + + - name: Get MariaDB version + ansible.builtin.shell: | + mariadb -Bse 'STATUS' | grep "^Server version:" + register: version + when: "{{ lookup('env', 'MARIADB_VERSION') }}" + + - name: Check MariaDB version + ansible.builtin.assert: + that: + - "'{{ lookup('env', 'MARIADB_VERSION') }}' in version.stdout" + msg: "{{ version.stdout }}" + when: "{{ lookup('env', 'MARIADB_VERSION') }}" + + - name: Check that Innodb engine is enabled (and default) + ansible.builtin.shell: | + mariadb -Bse 'SHOW ENGINES' | grep -qE '^InnoDB.DEFAULT.*YES.YES.YES$' + + - name: Check that default db exist + ansible.builtin.shell: | + mariadb -Bse 'SHOW DATABASES' | grep -q '^{{ item }}$' + loop: + - mysql + - information_schema + - performance_schema + + - name: Check that test db exist + ansible.builtin.shell: | + mariadb -Bse 'SHOW DATABASES' | grep -q '^{{ item }}$' + loop: + - db1 + - db2 + + - name: Do some SQL queries + ansible.builtin.shell: | + mariadb -Bse 'DROP DATABASE IF EXIST db' + mariadb -Bse 'CREATE DATABASE db' + mariadb -e 'CREATE TABLE db.t_innodb(a1 SERIAL, c1 CHAR(8)) ENGINE=InnoDB; INSERT INTO db.t_innodb VALUES (1,"foo"),(2,"bar")' + mariadb -e 'CREATE FUNCTION db.f() RETURNS INT DETERMINISTIC RETURN 1' + mariadb -e 'SHOW TABLES IN db' + mariadb -e 'SELECT * FROM db.t_innodb; INSERT INTO db.t_innodb VALUES (3,"foo"),(4,"bar")' + mariadb -e 'SELECT db.f()' diff --git a/requirements.txt b/requirements.txt index 1bd52fd..5b06de5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ ansible molecule==4.0.* molecule-podman -pytest-testinfra diff --git a/tasks/backup.yml b/tasks/backup.yml index d9f5670..e611014 100644 --- a/tasks/backup.yml +++ b/tasks/backup.yml @@ -1,8 +1,7 @@ --- - name: Install cron package - ansible.builtin.apt: - package: - - cron + ansible.builtin.package: + name: "{{ mariadb_cron_package_name }}" state: present - name: Deploy DB dump script diff --git a/tasks/configure.yml b/tasks/configure.yml index f691897..aecdc11 100644 --- a/tasks/configure.yml +++ b/tasks/configure.yml @@ -9,13 +9,16 @@ force: "{{ mariadb_overwrite_global_config_file }}" notify: Restart mariadb -- name: Create datadir if it does not exist +- name: Make sure datadir and log dir exist ansible.builtin.file: - path: "{{ mariadb_datadir }}" + path: "{{ item }}" state: directory - owner: mysql - group: mysql + owner: "{{ mariadb_user }}" + group: "{{ mariadb_user }}" mode: 0755 + loop: + - "{{ mariadb_data_dir }}" + - "{{ mariadb_log_dir }}" - name: Ensure MariaDB is started and enabled on boot ansible.builtin.service: diff --git a/tasks/main.yml b/tasks/main.yml index 093845b..54320d0 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,6 +1,21 @@ --- -- name: include task setup.yml - import_tasks: setup.yml +- name: Load OS-specific vars + ansible.builtin.include_vars: "{{ lookup('first_found', params) }}" + vars: + params: + files: + - "{{ ansible_distribution }}.yml" + - "{{ ansible_os_family }}.yml" + paths: + - "vars" + +- name: include task setup_debian.yml + import_tasks: setup_debian.yml + when: ansible_os_family == "Debian" + +- name: include task setup_redhat.yml + import_tasks: setup_redhat.yml + when: ansible_os_family == "RedHat" - name: include task configure.yml import_tasks: configure.yml diff --git a/tasks/setup.yml b/tasks/setup_debian.yml similarity index 56% rename from tasks/setup.yml rename to tasks/setup_debian.yml index ceb83e6..14fab41 100644 --- a/tasks/setup.yml +++ b/tasks/setup_debian.yml @@ -19,11 +19,32 @@ mode: "0644" when: mariadb_use_official_repo +- name: Determine distribution name (Debian sid pb) + ansible.builtin.set_fact: + distribution: "{% if 'n/a' in ansible_distribution_release %}sid{% else %}{{ ansible_distribution_release }}{% endif %}" + - name: Setup mariadb repository sourcelist entry ansible.builtin.copy: dest: /etc/apt/sources.list.d/mariadb.list content: | - deb {{ mariadb_use_official_repo_url }}/{{ mariadb_use_official_repo_version }}/{{ ansible_distribution | lower() }} {{ ansible_distribution_release }} main + # Ansible managed + deb {{ mariadb_use_official_repo_url }}/{{ mariadb_use_official_repo_version }}/{{ ansible_distribution | lower() }} {{ distribution }} main + owner: root + group: root + mode: "0644" + when: mariadb_use_official_repo + +- name: Prefer MariaDB repo over Debian repo + ansible.builtin.copy: + dest: /etc/apt/preferences.d/release + content: | + # Ansible managed + Package: * + Pin: origin {{ mariadb_use_official_repo_url | urlsplit('hostname') }} + Pin-Priority: 1000 + owner: root + group: root + mode: "0644" when: mariadb_use_official_repo - name: Install packages diff --git a/tasks/setup_redhat.yml b/tasks/setup_redhat.yml new file mode 100644 index 0000000..a0c49f9 --- /dev/null +++ b/tasks/setup_redhat.yml @@ -0,0 +1,42 @@ +--- +# //TEMP find a way to handle multiarch (see mirror.mariadb.org). +- name: Setup mariadb repository + ansible.builtin.copy: + dest: /etc/yum.repos.d/MariaDB.repo + content: | + # https://mariadb.org/download/ + [mariadb] + name = MariaDB + {% if ansible_distribution == "Fedora" %} + baseurl = https://yum.mariadb.org/{{ mariadb_use_official_repo_version }}/fedora{{ ansible_distribution_major_version }}-amd64 + {% else %} + baseurl = https://yum.mariadb.org/{{ mariadb_use_official_repo_version }}/rhel{{ ansible_distribution_major_version }}-amd64 + {% endif %} + gpgkey = https://yum.mariadb.org/RPM-GPG-KEY-MariaDB + module_hotfixes = 1 + gpgcheck = 1 + owner: root + group: root + mode: "0644" + when: mariadb_use_official_repo + +- name: Install packages + ansible.builtin.dnf: + name: + - mariadb-server + - python3-PyMySQL + state: present + +- name: Check if mariadb command exists + ansible.builtin.stat: + path: /usr/bin/mariadb + register: mariadb_cmd + +- name: Make sure that mariadb command exists + ansible.builtin.file: + src: /usr/bin/mysql + dest: /usr/bin/mariadb + owner: root + group: root + state: link + when: mariadb_cmd.stat.exists is false diff --git a/vars/Debian.yml b/vars/Debian.yml new file mode 100644 index 0000000..be01919 --- /dev/null +++ b/vars/Debian.yml @@ -0,0 +1,9 @@ +--- +mariadb_user: mysql +mariadb_config_file: "/etc/mysql/mariadb.cnf" +mariadb_data_dir: "/var/lib/mysql" +mariadb_pid_file: "/run/mysqld/mysqld.pid" +mariadb_unix_socket: "/run/mysqld/mysqld.sock" +mariadb_log_dir: "/var/log/mysql" +mariadb_log_error_file: "{{ mariadb_log_dir }}/error.log" +mariadb_cron_package_name: "cron" diff --git a/vars/RedHat.yml b/vars/RedHat.yml new file mode 100644 index 0000000..9c89f09 --- /dev/null +++ b/vars/RedHat.yml @@ -0,0 +1,9 @@ +--- +mariadb_user: mysql +mariadb_config_file: "/etc/my.cnf.d/mariadb-server.cnf" +mariadb_data_dir: "/var/lib/mysql" +mariadb_pid_file: "/run/mysqld.pid" +mariadb_unix_socket: "/var/lib/mysql/mysql.sock" +mariadb_log_dir: "/var/log/mariadb" +mariadb_log_error_file: "{{ mariadb_log_dir }}/error.log" +mariadb_cron_package_name: "cronie"