mirror of
https://github.com/mrlesmithjr/ansible-manage-lvm.git
synced 2026-02-04 08:49:13 +03:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d0feecec7 | ||
|
|
416e840eea | ||
|
|
850d571313 | ||
|
|
ff13947aaf | ||
|
|
26246c7160 | ||
|
|
5540f7fda5 | ||
|
|
433b7ca1a9 | ||
|
|
9404a780c5 | ||
|
|
c0184492d5 | ||
|
|
60e08852ea | ||
|
|
42cc915582 | ||
|
|
49edca9134 | ||
|
|
ee1e3d051b | ||
|
|
91f8cfca5d | ||
|
|
3ac9669088 | ||
|
|
4219da5423 | ||
|
|
683c617265 | ||
|
|
b41ffc5e58 | ||
|
|
564d3d1f6f | ||
|
|
1d0fa70d66 | ||
|
|
8c3bca39ec | ||
|
|
4fbcf1cd19 |
@@ -1,2 +1,3 @@
|
||||
skip_list:
|
||||
- name[casing]
|
||||
- role-name
|
||||
|
||||
6
.github/workflows/molecule.yml
vendored
6
.github/workflows/molecule.yml
vendored
@@ -20,14 +20,14 @@ jobs:
|
||||
python-version: [3.9]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
|
||||
|
||||
10
.github/workflows/release-galaxy.yml
vendored
10
.github/workflows/release-galaxy.yml
vendored
@@ -13,14 +13,14 @@ jobs:
|
||||
galaxy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- uses: actions/cache@v2
|
||||
python-version: '3.9'
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
|
||||
|
||||
28
README.md
28
README.md
@@ -4,6 +4,34 @@ Ansible role to manage LVM Groups/Logical Volumes.
|
||||
|
||||
> NOTE: Can be used to create, extend or resize LVM Groups and volumes.
|
||||
|
||||
## ⚠️ Important: Ansible Galaxy Role Name
|
||||
|
||||
**As of December 2025**, this role is available on Ansible Galaxy as:
|
||||
|
||||
```yaml
|
||||
- src: mrlesmithjr.manage_lvm # Note: underscore, not hyphen
|
||||
```
|
||||
|
||||
The previous role names (`mrlesmithjr.manage-lvm` and `mrlesmithjr.manage_lvm`) were
|
||||
consolidated into a single role. If you were using `mrlesmithjr.manage-lvm`, please
|
||||
update your `requirements.yml` to use `mrlesmithjr.manage_lvm`.
|
||||
|
||||
**Note:** This role is used by [OpenStack Kayobe](https://docs.openstack.org/kayobe/latest/)
|
||||
for LVM management. The `manage_lvm` name was preserved to maintain compatibility.
|
||||
|
||||
### Historical Download Statistics
|
||||
|
||||
Prior to consolidation, this role had accumulated significant usage:
|
||||
|
||||
| Role Name | Downloads (as of Dec 2025) |
|
||||
|-----------|---------------------------|
|
||||
| `mrlesmithjr.manage_lvm` | 697,492 |
|
||||
| `mrlesmithjr.manage-lvm` | 494,517 |
|
||||
| **Combined Total** | **1,192,009** |
|
||||
|
||||
Due to Ansible Galaxy limitations, download counts reset when roles are re-imported.
|
||||
The historical data above represents the actual community usage of this role.
|
||||
|
||||
## Requirements
|
||||
|
||||
Devices/disks to be members of the LVM setup **must be** identified prior to
|
||||
|
||||
@@ -9,6 +9,8 @@ lvm_groups: []
|
||||
# # defines if VG should exist or be removed
|
||||
# # true or false
|
||||
# create: true
|
||||
# # defines if PV should be resized to max size
|
||||
# pvresize: false
|
||||
# lvnames:
|
||||
# - lvname: swap_1
|
||||
# # Define size of lvol
|
||||
@@ -86,8 +88,5 @@ ebsnvme_binary_helper_path: '/sbin/go-ebsnvme'
|
||||
### nvme to scsi device name map script helper
|
||||
ebsnvme_scrip_helper_path: '/usr/local/bin/ebsnvme-id'
|
||||
|
||||
### auto pvresize (waiting until ansible 2.10 or above as collections have new lvg with integrated pvresize)
|
||||
### waiting for new module in collection set to true or run pvresize manually on remote systems
|
||||
### https://docs.ansible.com/ansible/3/collections/community/general/lvg_module.html
|
||||
###
|
||||
### resize all pv's to max size
|
||||
pvresize_to_max: false
|
||||
|
||||
@@ -3,7 +3,7 @@ galaxy_info:
|
||||
author: Larry Smith Jr.
|
||||
description: Ansible role to manage(create, extend, resize) LVM Groups/Logical Volumes.
|
||||
namespace: mrlesmithjr
|
||||
role_name: manage_lvm
|
||||
role_name: manage-lvm
|
||||
|
||||
license: MIT
|
||||
min_ansible_version: "1.2"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../default/tests
|
||||
20
molecule/kvm/tests/conftest.py
Normal file
20
molecule/kvm/tests/conftest.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""PyTest Fixtures."""
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
import pytest
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
"""Run tests only when under molecule with testinfra installed."""
|
||||
try:
|
||||
import testinfra
|
||||
except ImportError:
|
||||
pytest.skip("Test requires testinfra", allow_module_level=True)
|
||||
if "MOLECULE_INVENTORY_FILE" in os.environ:
|
||||
pytest.testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
|
||||
os.environ["MOLECULE_INVENTORY_FILE"]
|
||||
).get_hosts("all")
|
||||
else:
|
||||
pytest.skip(
|
||||
"Test should run only from inside molecule.", allow_module_level=True
|
||||
)
|
||||
33
molecule/kvm/tests/test_default.py
Normal file
33
molecule/kvm/tests/test_default.py
Normal file
@@ -0,0 +1,33 @@
|
||||
"""Role testing files using testinfra."""
|
||||
|
||||
|
||||
def test_lvm_package_shall_be_installed(host):
|
||||
assert host.package("lvm2").is_installed
|
||||
|
||||
|
||||
def test_non_persistent_volume_group_is_created(host):
|
||||
command = """sudo vgdisplay | grep -c 'my_vg'"""
|
||||
cmd = host.run(command)
|
||||
assert "1" in cmd.stdout
|
||||
|
||||
|
||||
def test_mylv_logical_volume_is_created(host):
|
||||
command = """sudo lvs -o lv_name my_vg --separator='|' --noheadings \
|
||||
| grep -c 'my_lv'"""
|
||||
cmd = host.run(command)
|
||||
assert int(cmd.stdout.rstrip()) >= 1
|
||||
|
||||
|
||||
def test_mylv_logical_volume2_is_created(host):
|
||||
command = """sudo lvs -o lv_name my_vg --separator='|' --noheadings \
|
||||
| grep -c 'my_lw'"""
|
||||
cmd = host.run(command)
|
||||
assert int(cmd.stdout.rstrip()) >= 1
|
||||
|
||||
|
||||
def test_volume_is_mounted(host):
|
||||
host.file("/var/lib/mountpoint").mode == 0o731
|
||||
|
||||
|
||||
def test_volume2_is_mounted(host):
|
||||
host.file("/var/lib/mountpoint2").mode == 0o731
|
||||
@@ -1 +0,0 @@
|
||||
../../default/tests/conftest.py
|
||||
20
molecule/kvmonlyvg/tests/conftest.py
Normal file
20
molecule/kvmonlyvg/tests/conftest.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""PyTest Fixtures."""
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
import pytest
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
"""Run tests only when under molecule with testinfra installed."""
|
||||
try:
|
||||
import testinfra
|
||||
except ImportError:
|
||||
pytest.skip("Test requires testinfra", allow_module_level=True)
|
||||
if "MOLECULE_INVENTORY_FILE" in os.environ:
|
||||
pytest.testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
|
||||
os.environ["MOLECULE_INVENTORY_FILE"]
|
||||
).get_hosts("all")
|
||||
else:
|
||||
pytest.skip(
|
||||
"Test should run only from inside molecule.", allow_module_level=True
|
||||
)
|
||||
@@ -1 +0,0 @@
|
||||
../../default/tests/conftest.py
|
||||
20
molecule/kvmsinglelv/tests/conftest.py
Normal file
20
molecule/kvmsinglelv/tests/conftest.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""PyTest Fixtures."""
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
import pytest
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
"""Run tests only when under molecule with testinfra installed."""
|
||||
try:
|
||||
import testinfra
|
||||
except ImportError:
|
||||
pytest.skip("Test requires testinfra", allow_module_level=True)
|
||||
if "MOLECULE_INVENTORY_FILE" in os.environ:
|
||||
pytest.testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
|
||||
os.environ["MOLECULE_INVENTORY_FILE"]
|
||||
).get_hosts("all")
|
||||
else:
|
||||
pytest.skip(
|
||||
"Test should run only from inside molecule.", allow_module_level=True
|
||||
)
|
||||
1715
poetry.lock
generated
1715
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ authors = ["Larry Smith Jr. <mrlesmithjr@gmail.com>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.9,<4.0"
|
||||
ansible = "6.6.0"
|
||||
ansible = "8.5.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
ansible-lint = "6.8.7"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
- lv.filesystem != "swap"
|
||||
|
||||
- name: create_fs | creating new filesystem on new LVM logical volume(s)
|
||||
community.general.system.filesystem:
|
||||
community.general.filesystem:
|
||||
fstype: "{{ lv.filesystem }}"
|
||||
dev: "/dev/{{ vg.vgname }}/{{ lv.lvname }}"
|
||||
resizefs: yes
|
||||
@@ -48,7 +48,7 @@
|
||||
- lv.filesystem != 'xfs'
|
||||
|
||||
- name: create_fs | creating new xfs filesystem on new LVM logical volume(s)
|
||||
community.general.system.filesystem:
|
||||
community.general.filesystem:
|
||||
fstype: "{{ lv.filesystem }}"
|
||||
dev: "/dev/{{ vg.vgname }}/{{ lv.lvname }}"
|
||||
opts: "{{ lv.fsopts | default(omit) }}"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
verbosity: 2
|
||||
|
||||
- name: create_lv | creating new LVM logical volume(s)
|
||||
community.general.system.lvol:
|
||||
community.general.lvol:
|
||||
vg: "{{ vg.vgname }}"
|
||||
lv: "{{ lv.lvname }}"
|
||||
size: "{{ lv.size }}"
|
||||
|
||||
@@ -1,27 +1,15 @@
|
||||
---
|
||||
- name: create_vg | creating new LVM volume group(s)
|
||||
community.general.system.lvg:
|
||||
community.general.lvg:
|
||||
vg: "{{ vg.vgname }}"
|
||||
pvs: "{{ vg.disks | join(',') }}"
|
||||
state: present
|
||||
pvresize: "{{ vg.pvresize | default(pvresize_to_max) }}"
|
||||
become: true
|
||||
when:
|
||||
- vg.create is defined
|
||||
- vg.create|bool
|
||||
|
||||
### workaround: auto pvresize waiting for upgrade to new module supporting integrated pvresize
|
||||
### ref: https://docs.ansible.com/ansible/3/collections/community/general/lvg_module.html
|
||||
- name: create_vg | pvresize to max available free space
|
||||
ansible.builtin.command: "pvresize {{ pv }}"
|
||||
loop: "{{ vg.disks | default([]) }}"
|
||||
loop_control:
|
||||
loop_var: pv
|
||||
changed_when: false
|
||||
when:
|
||||
- vg.create is defined
|
||||
- vg.create|bool
|
||||
- pvresize_to_max|bool
|
||||
|
||||
- name: manage_lvm | loop over logical volume group(s) to create logical volumes
|
||||
ansible.builtin.include_tasks: create_lv.yml
|
||||
loop: "{{ vg.lvnames | default([]) }}"
|
||||
|
||||
@@ -37,4 +37,4 @@
|
||||
ansible.builtin.command: "{{ rescan_scsi_command }}"
|
||||
become: true
|
||||
changed_when: false
|
||||
when: scsi_devices['stdout'] | length
|
||||
when: scsi_devices['stdout'] | length > 0
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
loop_var: vg
|
||||
|
||||
- name: manage_lvm | Removing LVM logical volume(s)
|
||||
community.general.system.lvol:
|
||||
community.general.lvol:
|
||||
vg: "{{ item.0.vgname }}"
|
||||
lv: "{{ item.1.lvname }}"
|
||||
state: absent
|
||||
@@ -20,7 +20,7 @@
|
||||
- not item.1.create|bool
|
||||
|
||||
- name: manage_lvm | Removing LVM volume group(s)
|
||||
community.general.system.lvg:
|
||||
community.general.lvg:
|
||||
vg: "{{ item.vgname }}"
|
||||
pvs: "{{ item.disks | join(',') }}"
|
||||
state: absent
|
||||
|
||||
Reference in New Issue
Block a user