add make_lv role
This commit is contained in:
68
roles/make_lv/README.md
Normal file
68
roles/make_lv/README.md
Normal file
@@ -0,0 +1,68 @@
|
||||
ansible-make-lv
|
||||
=========
|
||||
|
||||
Role for creating simple lv disks with 1 group and 1 volume
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
None
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
None
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
All variables
|
||||
```yaml
|
||||
roles:
|
||||
- role: genlab.ansible_make_lv
|
||||
virtual_group: "group"
|
||||
logical_volume: "volume"
|
||||
lvm_dev: "/dev/sda"
|
||||
size: 100%FREE
|
||||
fs_type: ext4
|
||||
storage_mountpoint: "/mnt"
|
||||
storage_mountpoint_mode: "0775"
|
||||
mountpoint_owner: root
|
||||
mountpoint_group: root
|
||||
is_container: false # disables udev in LVM if true
|
||||
```
|
||||
|
||||
Minimal variables
|
||||
```yaml
|
||||
roles:
|
||||
- role: genlab.ansible_make_lv
|
||||
virtual_group: "group"
|
||||
logical_volume: "volume"
|
||||
lvm_dev: "/dev/sda"
|
||||
```
|
||||
|
||||
Defaults
|
||||
```yaml
|
||||
size: 100%FREE
|
||||
fs_type: ext4
|
||||
storage_mountpoint: "/mnt"
|
||||
storage_mountpoint_mode: "0775"
|
||||
mountpoint_owner: root
|
||||
mountpoint_group: root
|
||||
is_container: false # disables udev in LVM if true
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
BSD
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
malyuk.ss@genlab.llc
|
||||
8
roles/make_lv/defaults/main.yml
Normal file
8
roles/make_lv/defaults/main.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
size: 100%FREE
|
||||
fs_type: ext4
|
||||
storage_mountpoint: "/mnt"
|
||||
storage_mountpoint_mode: "0775"
|
||||
mountpoint_owner: root
|
||||
mountpoint_group: root
|
||||
is_container: false
|
||||
1
roles/make_lv/handlers/main.yml
Normal file
1
roles/make_lv/handlers/main.yml
Normal file
@@ -0,0 +1 @@
|
||||
---
|
||||
17
roles/make_lv/meta/main.yml
Normal file
17
roles/make_lv/meta/main.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: "make_lv"
|
||||
namespace: genlab
|
||||
author: "Sergey Malyuk"
|
||||
company: "Genlab, LLC"
|
||||
description: ""
|
||||
license: "MIT"
|
||||
min_ansible_version: "2.1"
|
||||
|
||||
platforms:
|
||||
- name: "Ubuntu"
|
||||
versions: ["focal", "jammy", "noble"]
|
||||
|
||||
galaxy_tags: []
|
||||
|
||||
dependencies: []
|
||||
60
roles/make_lv/molecule/default/converge.yml
Normal file
60
roles/make_lv/molecule/default/converge.yml
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
pre_tasks:
|
||||
- name: Get /root/image.img stats
|
||||
ansible.builtin.stat:
|
||||
path: /root/image.img
|
||||
register: img_stat
|
||||
|
||||
- name: Create image file
|
||||
when: not img_stat.stat.exists
|
||||
ansible.builtin.command: dd if=/dev/zero of=/root/image.img bs=1M count=128
|
||||
register: dd_result
|
||||
changed_when: dd_result.rc == 0
|
||||
|
||||
- name: Get linked loop devices
|
||||
ansible.builtin.command: losetup -a
|
||||
changed_when: false
|
||||
register: loop_devs
|
||||
|
||||
- name: Link image to loop device
|
||||
when: "'/root/image.img' not in loop_devs.stdout"
|
||||
ansible.builtin.command: losetup --find --show -P /root/image.img
|
||||
register: loop_device
|
||||
changed_when: "'/dev/loop' in loop_device.stdout"
|
||||
|
||||
- name: Get all loop devices
|
||||
ansible.builtin.command: losetup -a
|
||||
register: losetup_out
|
||||
changed_when: false
|
||||
|
||||
- name: Find line with /root/image.img
|
||||
ansible.builtin.set_fact:
|
||||
matched_line: "{{ losetup_out.stdout_lines
|
||||
| select('search', '/root/image.img')
|
||||
| list
|
||||
| first
|
||||
| default('') }}"
|
||||
|
||||
- name: Extract loop device name (/dev/loopN)
|
||||
ansible.builtin.set_fact:
|
||||
loop_dev: "{{ matched_line | regex_search('(/dev/loop[0-9]+)', '\\1') | default('') }}"
|
||||
|
||||
- name: Debug result
|
||||
ansible.builtin.debug:
|
||||
msg: "/root/image.img is linked to {{ loop_dev[0] }}"
|
||||
when: loop_dev != ''
|
||||
|
||||
roles:
|
||||
- role: genlab.make_lv
|
||||
virtual_group: "group"
|
||||
logical_volume: "volume"
|
||||
lvm_dev: "{{ loop_dev[0] }}"
|
||||
size: 100%FREE
|
||||
fs_type: ext4
|
||||
storage_mountpoint: "/mnt"
|
||||
storage_mountpoint_mode: "0755"
|
||||
mountpoint_owner: root
|
||||
mountpoint_group: root
|
||||
is_container: true
|
||||
27
roles/make_lv/molecule/default/molecule.yml
Normal file
27
roles/make_lv/molecule/default/molecule.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
|
||||
driver:
|
||||
name: docker
|
||||
|
||||
platforms:
|
||||
- name: ubuntu
|
||||
image: geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2404}-ansible:latest
|
||||
pre_build_image: true
|
||||
command: ${MOLECULE_DOCKER_COMMAND:-""}
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:rw
|
||||
cgroupns_mode: host
|
||||
privileged: true
|
||||
|
||||
provisioner:
|
||||
name: ansible
|
||||
|
||||
verifier:
|
||||
name: ansible
|
||||
|
||||
lint: |
|
||||
set -e
|
||||
yamllint .
|
||||
ansible-lint .
|
||||
65
roles/make_lv/molecule/default/verify.yml
Normal file
65
roles/make_lv/molecule/default/verify.yml
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
- name: Verify
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
any_errors_fatal: true
|
||||
vars:
|
||||
virtual_group: "group"
|
||||
logical_volume: "volume"
|
||||
lvm_dev: "/dev/loop0"
|
||||
fs_type: ext4
|
||||
storage_mountpoint: "/mnt"
|
||||
|
||||
tasks:
|
||||
- name: Get volume group list
|
||||
ansible.builtin.shell:
|
||||
cmd: "set -o pipefail ; pvs | grep {{ lvm_dev }}"
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: vg_list
|
||||
|
||||
- name: Assert that volume group exists
|
||||
ansible.builtin.assert:
|
||||
that: virtual_group in vg_list.stdout
|
||||
success_msg: "{{ lvm_dev }} has {{ virtual_group }} group"
|
||||
fail_msg: "{{ lvm_dev }} DOES NOT have {{ virtual_group }} group"
|
||||
|
||||
- name: Get logical volume list
|
||||
ansible.builtin.shell:
|
||||
cmd: "set -o pipefail ; lvs | grep {{ virtual_group }} | grep {{ logical_volume }}"
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: lv_list
|
||||
|
||||
- name: Assert that logical volume exists
|
||||
ansible.builtin.assert:
|
||||
that: logical_volume in lv_list.stdout
|
||||
success_msg: "{{ virtual_group }} has {{ logical_volume }} volume"
|
||||
fail_msg: "{{ virtual_group }} DOES NOT have {{ logical_volume }} volume"
|
||||
|
||||
- name: Get filesystem type
|
||||
ansible.builtin.command: "blkid /dev/mapper/{{ virtual_group }}-{{ logical_volume }} -o value -s TYPE"
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: current_fs
|
||||
|
||||
- name: Assert that current filesystem is the required one
|
||||
ansible.builtin.assert:
|
||||
that: current_fs.stdout == fs_type
|
||||
success_msg: "{{ virtual_group }} - {{ logical_volume }} has {{ fs_type }} filesystem"
|
||||
fail_msg: "{{ virtual_group }} - {{ logical_volume }} DOES NOT have {{ fs_type }} filesystem"
|
||||
|
||||
- name: Get logical volume mount info # noqa: command-instead-of-module — tells ansible-lint to ignore the error, because you can't actually
|
||||
# do it with ansible.builtin.mount as the linter begs me to do
|
||||
ansible.builtin.shell: "mount | grep -w '{{ virtual_group }}-{{ logical_volume }}'"
|
||||
register: mount_check
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
||||
- name: Assert that volume is mounted
|
||||
ansible.builtin.assert:
|
||||
that: mount_check.rc == 0
|
||||
success_msg: "{{ virtual_group }}-{{ logical_volume }} is mounted at {{ storage_mountpoint }}"
|
||||
fail_msg: "{{ virtual_group }}-{{ logical_volume }} IS NOT mounted at {{ storage_mountpoint }}"
|
||||
102
roles/make_lv/tasks/main.yml
Normal file
102
roles/make_lv/tasks/main.yml
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
- name: Install LVM tools
|
||||
ansible.builtin.apt:
|
||||
name: lvm2
|
||||
state: present
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
- name: Check lvm storage exists
|
||||
block:
|
||||
- name: Get volume group list
|
||||
ansible.builtin.shell:
|
||||
cmd: "set -o pipefail ; pvs | grep {{ lvm_dev }}"
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: vg_list
|
||||
|
||||
- name: Assert that volume group exists
|
||||
ansible.builtin.assert:
|
||||
that: virtual_group in vg_list.stdout
|
||||
success_msg: "{{ lvm_dev }} has {{ virtual_group }} group"
|
||||
fail_msg: "{{ lvm_dev }} DOES NOT have {{ virtual_group }} group"
|
||||
|
||||
- name: Get logical volume list
|
||||
ansible.builtin.shell:
|
||||
cmd: "set -o pipefail ; lvs | grep {{ virtual_group }} | grep {{ logical_volume }}"
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: lv_list
|
||||
|
||||
- name: Assert that logical volume exists
|
||||
ansible.builtin.assert:
|
||||
that: logical_volume in lv_list.stdout
|
||||
success_msg: "{{ virtual_group }} has {{ logical_volume }} volume"
|
||||
fail_msg: "{{ virtual_group }} DOES NOT have {{ logical_volume }} volume"
|
||||
|
||||
- name: Get filesystem type
|
||||
ansible.builtin.command: "blkid /dev/mapper/{{ virtual_group }}-{{ logical_volume }} -o value -s TYPE"
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: current_fs
|
||||
|
||||
- name: Assert that current filesystem is the required one
|
||||
ansible.builtin.assert:
|
||||
that: current_fs.stdout == fs_type
|
||||
success_msg: "{{ virtual_group }} - {{ logical_volume }} has {{ fs_type }} filesystem"
|
||||
fail_msg: "{{ virtual_group }} - {{ logical_volume }} DOES NOT have {{ fs_type }} filesystem"
|
||||
|
||||
rescue:
|
||||
- name: Unmount the main storage
|
||||
ansible.posix.mount:
|
||||
src: "/dev/{{ virtual_group }}/{{ logical_volume }}"
|
||||
path: "{{ storage_mountpoint }}"
|
||||
state: absent
|
||||
|
||||
- name: Wipe disk signatures
|
||||
ansible.builtin.command: "wipefs -af {{ lvm_dev }}"
|
||||
register: wipefs_result
|
||||
changed_when: wipefs_result.rc == 0
|
||||
|
||||
- name: Create a volume group for the storage
|
||||
community.general.lvg:
|
||||
pvs: "{{ lvm_dev }}"
|
||||
vg: "{{ virtual_group }}"
|
||||
force: true
|
||||
|
||||
- name: Create a logical volume for the storage
|
||||
when: is_container
|
||||
community.general.lvol:
|
||||
vg: "{{ virtual_group }}"
|
||||
lv: "{{ logical_volume }}"
|
||||
size: "{{ size }}"
|
||||
opts: "--config 'activation/udev_rules=0'"
|
||||
|
||||
- name: Create a logical volume for the storage
|
||||
when: not is_container
|
||||
community.general.lvol:
|
||||
vg: "{{ virtual_group }}"
|
||||
lv: "{{ logical_volume }}"
|
||||
size: "{{ size }}"
|
||||
opts: "--config 'activation/udev_rules=1'"
|
||||
|
||||
- name: Create a filesystem for the storage
|
||||
community.general.filesystem:
|
||||
dev: "/dev/{{ virtual_group }}/{{ logical_volume }}"
|
||||
fstype: "{{ fs_type }}"
|
||||
|
||||
- name: Create a mountpoint for the storage
|
||||
ansible.builtin.file:
|
||||
path: "{{ storage_mountpoint }}"
|
||||
state: directory
|
||||
owner: "{{ mountpoint_owner }}"
|
||||
group: "{{ mountpoint_group }}"
|
||||
mode: "{{ storage_mountpoint_mode }}"
|
||||
|
||||
- name: Mount the main storage
|
||||
ansible.posix.mount:
|
||||
src: "/dev/{{ virtual_group }}/{{ logical_volume }}"
|
||||
path: "{{ storage_mountpoint }}"
|
||||
fstype: "{{ fs_type }}"
|
||||
state: mounted
|
||||
1
roles/make_lv/vars/main.yml
Normal file
1
roles/make_lv/vars/main.yml
Normal file
@@ -0,0 +1 @@
|
||||
---
|
||||
Reference in New Issue
Block a user