Re-add local copy of infra.lvm_snapshots so we can better tailor the lab experience

This commit is contained in:
2025-01-31 16:28:01 -05:00
parent 3c5f740320
commit 8e194f9fe5
81 changed files with 2955 additions and 0 deletions

View File

@ -0,0 +1,39 @@
# Testing the LVM Snapshot Role
## Prerequisites
- All the tests are in the form of ansible playbooks.
- All playbooks expect that the target machine will have a secondary storage device to be used for testing.
## Variables
The variables may be passed as part of the inventory or using a separate file.
```yaml
device: < device node without `/dev`. e.g. vdb >
```
## Ansible Configuration
In order to run the tests from the repo without having to install them,
the tests directory includes an [ansible.cfg](./ansible.cfg) file.
Make sure to point to it when running the test playbook
## Running a test
### Inventory file
In this example, the `device` parameter is passed in the `inventory.yml` file
```yaml
all:
hosts:
<FQDN of test machine>:
device: vdb
```
### Command line
Running the [snapshot revert playbook](./test-revert-playbook.yml) test from the repo
```bash
ANSIBLE_CONFIG=./tests/ansible.cfg ansible-playbook -K -i inventory.yml tests/test-revert-playbook.yml
```

View File

@ -0,0 +1,2 @@
[defaults]
roles_path=~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:../roles

View File

@ -0,0 +1,15 @@
- name: Generate snapshot list out of volumes list
ansible.builtin.set_fact:
_snapshots: "{{ (_snapshots | default([])) + [{'vg': volume_group, 'lv': item.name, 'size': item.size}] }}"
loop: "{{ volumes }}"
- name: Create the snapshot
vars:
snapshot_create_volumes: "{{ _snapshots }}"
snapshot_create_set_name: "{{ snapshot_set_name }}"
ansible.builtin.include_role:
name: snapshot_create
- name: Verify that the snapshot was created
ansible.builtin.include_tasks: verify-snapshot-created.yml
loop: "{{ volumes }}"

View File

@ -0,0 +1,40 @@
- name: Fill the volume
block:
- name: Set the retry count
ansible.builtin.set_fact:
_retry_count: "{{ (_retry_count | default('-1') | int) + 1 }}"
- name: Generate the Sub-Directory name
ansible.builtin.set_fact:
_sub_dir_name: "{{ lookup('community.general.random_string', upper=false, numbers=false, special=false) }}"
- name: Make a copy of the boot partition
ansible.builtin.copy:
src: /boot
dest: "{{ test_directory }}/{{ _sub_dir_name }}"
remote_src: true
mode: '0777'
- name: Get the status of the snapshot
ansible.builtin.command: "lvs --select 'lv_name = {{ volume_name }}_{{ snapshot_set_name }}' --reportformat json"
register: _lv_status_check
changed_when: false
- name: Store the snapshot data_percent
ansible.builtin.set_fact:
_snapshot_data_percent: "{{ ((_lv_status_check.stdout | from_json).report[0].lv[0].data_percent) }}"
- name: Check if snapshot is full enough
ansible.builtin.assert:
that: _snapshot_data_percent|float > snapshot_fill_percent|float
quiet: true
rescue:
- name: Check the retry count to avoid endless loop
ansible.builtin.assert:
that: (_retry_count|int) < (snapshot_max_retry|int)
fail_msg: "Ended after {{ snapshot_max_retry }} retries"
success_msg: "Volume is not full enough ({{ _snapshot_data_percent }}) - Run again..."
- name: Include the same tasks file again
ansible.builtin.include_tasks: fill-snapshot.yml

View File

@ -0,0 +1,11 @@
- name: Unmount the "{{ item.directory }}"
ansible.posix.mount:
path: "{{ item.directory }}"
state: absent
- name: Remove the logical volume
community.general.lvol:
vg: "{{ volume_group }}"
lv: "{{ item.name }}"
force: true
state: absent

View File

@ -0,0 +1,25 @@
- name: Cleanup the volumes
ansible.builtin.include_tasks: post-test-clean-volume.yml
loop: "{{ volumes }}"
- name: Remove the volume group
community.general.lvg:
vg: "{{ volume_group }}"
pvs: "/dev/{{ device }}1"
state: absent
- name: Remove the PV
ansible.builtin.command: "pvremove /dev/{{ device }}1"
changed_when: true
- name: Cleanup the system.devices file
ansible.builtin.lineinfile:
path: /etc/lvm/devices/system.devices
regexp: "IDTYPE=devname IDNAME=/dev/{{ device }}1 DEVNAME=/dev/{{ device }}1 PVID=. PART=1"
state: absent
- name: Delete the partition
community.general.parted:
device: "/dev/{{ device }}"
number: 1
state: absent

View File

@ -0,0 +1,18 @@
- name: Create the logical volume
community.general.lvol:
vg: "{{ volume_group }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
force: true
- name: Format the ext4 filesystem
community.general.filesystem:
fstype: ext4
dev: "/dev/{{ volume_group }}/{{ item.name }}"
- name: Mount the lv on "{{ item.directory }}"
ansible.posix.mount:
path: "{{ item.directory }}"
src: "/dev/{{ volume_group }}/{{ item.name }}"
fstype: ext4
state: mounted

View File

@ -0,0 +1,23 @@
- name: Create partition
community.general.parted:
device: "/dev/{{ device }}"
number: 1
part_end: 9GiB
flags:
- lvm
state: present
- name: Install lvm2 dependency
ansible.builtin.package:
name: lvm2
state: present
- name: Create the volume group
community.general.lvg:
vg: "{{ volume_group }}"
pvs: "/dev/{{ device }}1"
pesize: 16
- name: Create and prepare the volumes
ansible.builtin.include_tasks: pre-test-prepare-volume.yml
loop: "{{ volumes }}"

View File

@ -0,0 +1,24 @@
- name: Run lvs
ansible.builtin.command: lvs --select 'vg_name = {{ volume_group }} && origin = {{ item.name }}' --reportformat json
register: lvs_response
changed_when: false
- name: Parse report
ansible.builtin.set_fact:
lv_snapshot_array: "{{ (lvs_response.stdout | from_json).report[0].lv }}"
- name: Verify that the the snapshot exists
ansible.builtin.assert:
that: (lv_snapshot_array | length) == 1
fail_msg: >
The snapshot for {{ item.name }} was not created
- name: Get the snapshot name
ansible.builtin.set_fact:
snapshot_name: "{{ lv_snapshot_array[0].lv_name | default('n/a') }}"
- name: Verify that the the snapshot was named correctly
ansible.builtin.assert:
that: snapshot_name == item.name + '_' + snapshot_set_name
fail_msg: >
Snapshot name '{{ snapshot_name }}' is not as expected {{ item.name }}_{{ snapshot_set_name }}

View File

@ -0,0 +1,16 @@
- name: Run lvs
ansible.builtin.command: lvs --select 'vg_name = {{ volume_group }} && lv_name = {{ volume_name }}_{{ snapshot_set_name }}' --reportformat json
register: lvs_response
changed_when: false
- name: Parse report
ansible.builtin.set_fact:
lv_snapshot_report_array: "{{ (lvs_response.stdout | from_json).report[0].lv }}"
- name: Verify that the snapshot no longer exists
ansible.builtin.assert:
that: (lv_snapshot_report_array | length) == 0
fail_msg: >
The snapshot '{{ volume_name }}_{{ snapshot_set_name }}'' for
volume '{{ volume_name }}' in volume group '{{ volume_group }}'
still exists