Add cluster testing in CI (close #26)

This commit is contained in:
Faustin Lammler 2022-10-12 14:01:19 +02:00
parent bc0663c9f3
commit 904a107ae1
No known key found for this signature in database
GPG Key ID: 390A2F27832A5C79
13 changed files with 415 additions and 24 deletions

69
.github/workflows/test_cluster.yml vendored Normal file
View File

@ -0,0 +1,69 @@
---
name: Cluster deployment
on:
push:
paths:
- .github/workflows/test_cluster.yml
- requirements.txt
- "files/**"
- "handlers/**"
- "molecule/cluster/**"
- "tasks/**"
- "templates/**"
- "vars/**"
pull_request:
paths:
- .github/workflows/test_cluster.yml
- requirements.txt
- "files/**"
- "handlers/**"
- "molecule/cluster/**"
- "tasks/**"
- "templates/**"
- "vars/**"
schedule:
- cron: "30 5 * * 2"
jobs:
molecule-distrib-pkg:
name: Cluster
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
distro:
# - ubuntu-18.04
# - ubuntu-20.04
- ubuntu-22.04
# - debian-10
- debian-11
# - debian-sid
# - fedora-36
- fedora-37
# - almalinux-8
- almalinux-9
- rockylinux-8
# - rockylinux-9
playbook:
- converge.yml
steps:
- uses: actions/checkout@v3
- name: Install requirements
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
# This is necessary on GH Actions to allow running systemd in rootless containers
# see: https://github.com/actions/virtual-environments/issues/3536
# see: https://github.com/ansible-community/molecule/discussions/3155
- name: Start systemd user service
run: |
loginctl enable-linger $(whoami)
sleep 1
- name: Run molecule
run: molecule test -s cluster
env:
PY_COLORS: "1"
ANSIBLE_FORCE_COLOR: "1"
MOLECULE_DISTRO: ${{ matrix.distro }}
MOLECULE_PLAYBOOK: ${{ matrix.playbook }}

View File

@ -8,7 +8,7 @@ on:
- requirements.txt - requirements.txt
- "files/**" - "files/**"
- "handlers/**" - "handlers/**"
- "molecule/**" - "molecule/default/**"
- "tasks/**" - "tasks/**"
- "templates/**" - "templates/**"
- "vars/**" - "vars/**"
@ -18,7 +18,7 @@ on:
- requirements.txt - requirements.txt
- "files/**" - "files/**"
- "handlers/**" - "handlers/**"
- "molecule/**" - "molecule/default/**"
- "tasks/**" - "tasks/**"
- "templates/**" - "templates/**"
- "vars/**" - "vars/**"

View File

@ -8,7 +8,7 @@ on:
- requirements.txt - requirements.txt
- "files/**" - "files/**"
- "handlers/**" - "handlers/**"
- "molecule/**" - "molecule/default/**"
- "tasks/**" - "tasks/**"
- "templates/**" - "templates/**"
- "vars/**" - "vars/**"
@ -18,7 +18,7 @@ on:
- requirements.txt - requirements.txt
- "files/**" - "files/**"
- "handlers/**" - "handlers/**"
- "molecule/**" - "molecule/default/**"
- "tasks/**" - "tasks/**"
- "templates/**" - "templates/**"
- "vars/**" - "vars/**"

View File

@ -0,0 +1,7 @@
---
- name: Converge
hosts: all
gather_facts: true
roles:
- role: ansible-role-mariadb

View File

@ -0,0 +1,71 @@
---
driver:
name: podman
platforms:
- name: node1
image: "fauust/docker-ansible:${MOLECULE_DISTRO:-debian-11}"
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
override_command: false
pre_build_image: true
network: local
- name: node2
image: "fauust/docker-ansible:${MOLECULE_DISTRO:-debian-11}"
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
override_command: false
pre_build_image: true
groups:
- replica
network: local
- name: node3
image: "fauust/docker-ansible:${MOLECULE_DISTRO:-debian-11}"
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
override_command: false
pre_build_image: true
groups:
- replica
network: local
provisioner:
name: ansible
inventory:
group_vars:
all:
mariadb_replication_user:
- name: ReplicationUser
password: ReplicationPassword
state: present
replica:
mariadb_replication_role: replica
mariadb_replication_master_ip: node1
host_vars:
node1:
mariadb_server_id: 1
mariadb_bind_address: 0.0.0.0
mariadb_replication_role: master
mariadb_max_binlog_size: 100M
mariadb_binlog_format: MIXED
mariadb_expire_logs_days: 10
mariadb_databases:
- name: db
state: present
replicate: true
node2:
mariadb_server_id: 2
node3:
mariadb_server_id: 3
env:
ANSIBLE_GATHERING: explicit
ANSIBLE_FORCE_COLOR: true
playbooks:
converge: ${MOLECULE_PLAYBOOK:-converge.yml}
verifier:
name: ansible
scenario:
name: cluster
test_sequence:
- create
- converge
- idempotence
- verify

View File

@ -0,0 +1,34 @@
---
- name: Verify setup
hosts: all
tasks:
- 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: Verify replication
hosts: replica
tasks:
- name: Check that test db exist (created only on master)
ansible.builtin.shell: |
mariadb -Bse 'SHOW DATABASES' | grep -q '^{{ item }}$'
loop:
- db
- name: Get replica status
ansible.builtin.shell: |
mariadb -Bse 'SHOW SLAVE STATUS\G'
register: replica_status
- name: Check that replication is working
ansible.builtin.assert:
that:
- "'Waiting for master to send event' in replica_status.stdout"
msg: "{{ replica_status.stdout }}"

View File

@ -0,0 +1,9 @@
---
- name: Converge
hosts: all
gather_facts: true
vars_files: vars/testvars.yml
become: true
roles:
- role: ansible-role-mariadb

View File

@ -0,0 +1,38 @@
---
dependency:
name: galaxy
driver:
name: vagrant
provider:
name: libvirt
platforms:
- name: node1
box: ${TESTBOX:-debian/buster64}
interfaces:
- network_name: private_network
ip: 192.168.56.11
memory: 1024
cpus: 2
provider_options:
# using session with network leads to troubles
qemu_use_session: false
config_options:
synced_folder: true
instance_raw_config_args:
- 'vm.synced_folder ".", "/vagrant", type: "rsync"'
- name: node2
box: ${TESTBOX:-debian/bullseye64}
interfaces:
- network_name: private_network
ip: 192.168.56.12
memory: 1024
cpus: 2
provider_options:
# using session with network leads to troubles
qemu_use_session: false
instance_raw_config_args:
- 'vm.synced_folder ".", "/vagrant", type: "rsync"'
provisioner:
name: ansible
scenario:
name: vagrant

View File

@ -0,0 +1 @@
../../../vars/Debian.yml

View File

@ -0,0 +1 @@
../../../vars/RedHat.yml

View File

@ -0,0 +1,47 @@
---
mariadb_server_id: 1
mariadb_bind_address: 0.0.0.0
mariadb_replication_role: master
mariadb_innodb_raw: |
innodb_buffer_pool_size = 512M
innodb_log_file_size = 64M
innodb_file_per_table = 1
mariadb_databases:
- name: db1
collation: latin1_swedish_ci
encoding: latin1
state: present
- name: db2
state: present
replicate: true
mariadb_users:
- name: user1
host: "%"
password: user1passwd
priv: "db2.*:SELECT"
state: present
- name: user2
host: 100.64.10.3
password: user2passwd
priv: "db2.*:ALL"
state: present
mariadb_replication_user:
- name: ReplicationUser
host: 100.64.10.33
password: ReplicationPassword
state: present
# backup
mariadb_backup_db: true
mariadb_backup_db_cron_min: "50"
mariadb_backup_db_cron_hour: "00"
mariadb_backup_db_dir: "/mnt/backup"
mariadb_backup_db_rotation: "15"
mariadb_backup_db_name:
- db1
- db2

116
molecule/vagrant/verify.yml Normal file
View File

@ -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: |
sudo 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: |
sudo mariadb -Bse 'SHOW ENGINES' | grep -qE '^InnoDB.DEFAULT.*YES.YES.YES$'
- name: Check that default db exist
ansible.builtin.shell: |
sudo mariadb -Bse 'SHOW DATABASES' | grep -q '^{{ item }}$'
loop:
- mysql
- information_schema
- performance_schema
- name: Check that test db exist
ansible.builtin.shell: |
sudo mariadb -Bse 'SHOW DATABASES' | grep -q '^{{ item }}$'
loop:
- db1
- db2
- name: Do some SQL queries
ansible.builtin.shell: |
sudo mariadb -Bse 'DROP DATABASE IF EXIST db'
sudo mariadb -Bse 'CREATE DATABASE db'
sudo mariadb -e 'CREATE TABLE db.t_innodb(a1 SERIAL, c1 CHAR(8)) ENGINE=InnoDB; INSERT INTO db.t_innodb VALUES (1,"foo"),(2,"bar")'
sudo mariadb -e 'CREATE FUNCTION db.f() RETURNS INT DETERMINISTIC RETURN 1'
sudo mariadb -e 'SHOW TABLES IN db'
sudo mariadb -e 'SELECT * FROM db.t_innodb; INSERT INTO db.t_innodb VALUES (3,"foo"),(4,"bar")'
sudo mariadb -e 'SELECT db.f()'

View File

@ -6,32 +6,30 @@
register: replica register: replica
no_log: true no_log: true
# For the moment, we have to use a sql command. # # Keeping this for the record
# In ansible 2.10, we should be able to use mysql_replication module. # # See https://github.com/ansible/ansible/pull/62648
# See https://github.com/ansible/ansible/pull/62648 (and below) # - name: Configure replication on the replica
# ansible.builtin.command: |
# /usr/bin/mariadb -e "CHANGE MASTER TO master_host='{{ mariadb_replication_master_ip }}',
# master_user='{{ item.name }}', master_password='{{ item.password }}', master_use_gtid=slave_pos"
# loop: "{{ mariadb_replication_user }}"
# when:
# - not replica.Is_Replica
# no_log: true
- name: Configure replication on the replica - name: Configure replication on the replica
ansible.builtin.command: | community.mysql.mysql_replication:
/usr/bin/mariadb -e "CHANGE MASTER TO master_host='{{ mariadb_replication_master_ip }}', mode: changeprimary
master_user='{{ item.name }}', master_password='{{ item.password }}', master_use_gtid=slave_pos" master_host: "{{ mariadb_replication_master_ip }}"
master_user: "{{ item.name }}"
master_password: "{{ item.password }}"
master_use_gtid: "{{ mariadb_replication_gtid | default('replica_pos') }}"
login_unix_socket: "{{ mariadb_unix_socket }}"
loop: "{{ mariadb_replication_user }}" loop: "{{ mariadb_replication_user }}"
when: when:
- not replica.Is_Replica - not replica.Is_Replica
no_log: true no_log: true
# # Following (not tested) should work on ansible 2.10
# - name: Configure replication on the replica
# mysql_replication:
# mode: changemaster
# master_host: "{{ mariadb_replication_master_ip }}"
# master_user: "{{ item.name }}"
# master_password: "{{ item.password }}"
# master_use_gtid: "{{ mariadb_replication_gtid | default('slave_pos') }}
# login_unix_socket: "{{ mariadb_unix_socket }}"
# loop: "{{ mariadb_replication_user }}"
# when:
# - not replica.Is_Slave
# no_log: true
- name: Reset replica replication - name: Reset replica replication
community.mysql.mysql_replication: community.mysql.mysql_replication:
mode: resetreplica mode: resetreplica