Merge pull request #63 from corvus-migratorius/role-xfs_project_quotas

Role xfs project quotas
This commit is contained in:
Fogucoco
2026-02-19 17:15:29 +03:00
committed by GitHub
12 changed files with 262 additions and 1 deletions

View File

@@ -37,3 +37,4 @@
- [users](roles/users/README.md)
- [wg_hub](roles/wg_hub/README.md)
- [wg_spoke](roles/wg_spoke/README.md)
- [xfs_project_quotas](roles/xfs_project_quotas/README.md)

View File

@@ -1,7 +1,7 @@
---
namespace: genlab
name: common
version: 0.32.0
version: 0.33.0
readme: README.md
authors:
- Alexander Gorelyshev (corvus-migratorius@proton.me)

View File

@@ -0,0 +1,35 @@
xfs_project_quotas
=========
Sets up XFS quotas
Requirements
------------
- `xfsprogs` package
Role Variables
--------------
- `projects` — quota directories list
- `storage_mountpoint` — XFS mountpoint
<!-- Dependencies
------------
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. -->
Example Playbook
----------------
See [converge.yml](molecule/default/converge.yml)
License
-------
BSD
Author Information
------------------
Alexander Gorelyshev (corvus-migratorius@proton.me)

View File

@@ -0,0 +1,2 @@
---
# defaults file for xfs_project_quotas

View File

@@ -0,0 +1,2 @@
---
# handlers file for xfs_project_quotas

View File

@@ -0,0 +1,16 @@
galaxy_info:
role_name: xfs_project_quotas
namespace: genlab
author: Alexander Gorelyshev
company: Genlab, LLC
description: ""
license: GPL-2.0-or-later
min_ansible_version: "2.1"
platforms:
- name: Ubuntu
versions: ["jammy", "noble"]
galaxy_tags: []
dependencies: []

View File

@@ -0,0 +1,16 @@
- id: 100
path: /mnt/test0
name: test0
bsoft: "100M"
bhard: "100M"
owner: root
group: root
mode: "0700"
- id: 101
path: /mnt/test1
name: test1
bsoft: "100M"
bhard: "100M"
owner: root
group: root
mode: "0700"

View File

@@ -0,0 +1,72 @@
---
- name: Converge
hosts: all
pre_tasks:
- name: Get /root/image.img stats
ansible.builtin.stat:
path: /root/image.img
register: xfs_project_quotas_img_stat
- name: Create image file
when: not xfs_project_quotas_img_stat.stat.exists
ansible.builtin.command: dd if=/dev/zero of=/root/image.img bs=1M count=400
register: xfs_project_quotas_dd_result
changed_when: xfs_project_quotas_dd_result.rc == 0
- name: Get linked loop devices
ansible.builtin.command: losetup -a
changed_when: false
register: xfs_project_quotas_loop_devs
- name: Link image to loop device
when: "'/root/image.img' not in xfs_project_quotas_loop_devs.stdout"
ansible.builtin.command: losetup --find --show -P /root/image.img
register: xfs_project_quotas_loop_device
changed_when: "'/dev/loop' in xfs_project_quotas_loop_device.stdout"
- name: Get all loop devices
ansible.builtin.command: losetup -a
register: xfs_project_quotas_losetup_out
changed_when: false
- name: Find line with /root/image.img
ansible.builtin.set_fact:
xfs_project_quotas_matched_line: "{{ xfs_project_quotas_losetup_out.stdout_lines
| select('search', '/root/image.img')
| list
| first
| default('') }}"
- name: Extract loop device name (/dev/loopN)
ansible.builtin.set_fact:
xfs_project_quotas_loop_dev: "{{ xfs_project_quotas_matched_line | regex_search('(/dev/loop[0-9]+)', '\\1') | default('') }}"
- name: Debug result
ansible.builtin.debug:
msg: "/root/image.img is linked to {{ xfs_project_quotas_loop_dev[0] }}"
when: xfs_project_quotas_loop_dev != ''
- name: "Quotas | Ensure xfsprogs package is installed"
ansible.builtin.apt:
name: xfsprogs
state: present
update_cache: true
cache_valid_time: 3600
- name: Make xfs filesystem
community.general.filesystem:
fstype: xfs
dev: "{{ xfs_project_quotas_loop_dev[0] }}"
- name: Mount xfs virtual disk
ansible.posix.mount:
path: /mnt
src: /root/image.img
fstype: xfs
opts: defaults,prjquota
state: mounted
roles:
- role: genlab.common.xfs_project_quotas
projects: "{{ lookup('file', 'configuration/example.yml') | from_yaml }}"
storage_mountpoint: "/mnt"

View 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 .

View File

@@ -0,0 +1,13 @@
---
- name: Verify
hosts: all
gather_facts: false
any_errors_fatal: true
tasks:
- name: Check XFS project quotas on /mnt
ansible.builtin.command: xfs_quota -x -c 'report -p' /mnt
register: xfs_project_quotas_quota_output
changed_when: false
failed_when: "'Project quota on /mnt' not in xfs_project_quotas_quota_output.stdout"

View File

@@ -0,0 +1,75 @@
---
- name: Check files
loop:
- /etc/projects
- /etc/projid
ansible.builtin.stat:
path: "{{ item }}"
register: xfs_project_quotas_proj_files
- name: Create missing files
loop: "{{ xfs_project_quotas_proj_files.results }}"
when: not item.stat.exists
ansible.builtin.file:
path: "{{ item.invocation.module_args.path }}"
state: touch
owner: root
group: root
mode: "0644"
- name: "Quotas | Ensure xfsprogs package is installed"
ansible.builtin.apt:
name: xfsprogs
state: present
update_cache: true
cache_valid_time: 3600
- name: "Quotas | Ensure all /etc/projects entries exist"
loop: "{{ projects }}"
ansible.builtin.lineinfile:
path: /etc/projects
state: present
backup: true
regexp: "^{{ item.id }}:"
line: "{{ item.id }}:{{ item.path }}"
- name: "Quotas | Ensure all /etc/projects entries exist"
loop: "{{ projects }}"
ansible.builtin.lineinfile:
path: /etc/projid
state: present
backup: true
regexp: "^{{ item.name }}:"
line: "{{ item.name }}:{{ item.id }}"
- name: "Quotas | Ensure all project paths exist"
loop: "{{ projects }}"
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
owner: "{{ item.owner }}"
group: "{{ item.group }}"
mode: "{{ item.mode }}"
- name: "Quotas | Initialize project quotas"
changed_when: false
loop: "{{ projects }}"
ansible.builtin.command:
cmd: >-
xfs_quota
-x
-c
'project -s {{ item.name }}'
{{ storage_mountpoint }}
- name: "Quotas | Apply quota limits"
loop: "{{ projects }}"
community.general.xfs_quota:
type: project
name: "{{ item.name }}"
mountpoint: "{{ storage_mountpoint }}"
bsoft: "{{ item.bsoft | default('100G', false) }}"
bhard: "{{ item.bhard | default('100G', false) }}"
isoft: "{{ item.isoft | default(0, false) }}"
ihard: "{{ item.ihard | default(0, false) }}"
state: present

View File

@@ -0,0 +1,2 @@
---
# vars file for xfs_project_quotas