Re-add local copy of infra.lvm_snapshots so we can better tailor the lab experience
This commit is contained in:
@ -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
|
||||
```
|
@ -0,0 +1,2 @@
|
||||
[defaults]
|
||||
roles_path=~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:../roles
|
@ -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 }}"
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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 }}"
|
@ -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 }}
|
@ -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
|
Reference in New Issue
Block a user