feat(expand_root_lv): new role to grow root LV to fill VG + resize fs
Reclaims the half-disk LV left by the Ubuntu Server autoinstall template default. Idempotent — no-ops cleanly when there are no free PE in the VG, and exits the play cleanly on hosts without LVM. Supports ext4 and xfs. Does not handle partition resize (cloud-utils growpart) — out of scope for the template fix-up case. Wired into day1_deploy_honcho.yml ahead of the honcho role so newly provisioned VMs get the fix-up automatically. Suitable to add to any day1 playbook by simply listing it before the application role.
This commit is contained in:
@@ -5,6 +5,9 @@
|
|||||||
# Deploys Honcho + pgvector PostgreSQL on the `lincoln` host. Run AFTER
|
# Deploys Honcho + pgvector PostgreSQL on the `lincoln` host. Run AFTER
|
||||||
# day0_linux_baseline.yml has been applied to the target.
|
# day0_linux_baseline.yml has been applied to the target.
|
||||||
#
|
#
|
||||||
|
# expand_root_lv runs first to reclaim any unallocated space left by the
|
||||||
|
# Ubuntu autoinstall template (half-disk LV pattern).
|
||||||
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ansible-playbook -i inventory.yml playbooks/day1_deploy_honcho.yml
|
# ansible-playbook -i inventory.yml playbooks/day1_deploy_honcho.yml
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@@ -14,4 +17,5 @@
|
|||||||
become: true
|
become: true
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
roles:
|
roles:
|
||||||
|
- expand_root_lv
|
||||||
- honcho
|
- honcho
|
||||||
|
|||||||
63
ansible/roles/expand_root_lv/README.md
Normal file
63
ansible/roles/expand_root_lv/README.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# expand-root-lv role
|
||||||
|
|
||||||
|
Idempotent role that extends the root LVM logical volume to fill its
|
||||||
|
volume group and grows the underlying filesystem (ext4 or xfs).
|
||||||
|
|
||||||
|
## Why this role exists
|
||||||
|
|
||||||
|
The Ubuntu Server autoinstall template (used by the mk-labs `wed`-baked
|
||||||
|
VM templates) provisions the root LV at roughly half the available disk
|
||||||
|
size — a longstanding installer default that surprises everyone who
|
||||||
|
hasn't been bitten by it before. Every freshly-provisioned VM in mk-labs
|
||||||
|
needs this fix-up before it's fully useful.
|
||||||
|
|
||||||
|
## Idempotency
|
||||||
|
|
||||||
|
- If `vg_free_count == 0`, the `lvextend` step is skipped and the
|
||||||
|
filesystem-grow step is also skipped (nothing to resize against).
|
||||||
|
- If the target volume group doesn't exist on the host (e.g. a non-LVM
|
||||||
|
layout), the role exits cleanly via `meta: end_play`.
|
||||||
|
- Safe to leave in a day1 deploy playbook so future disk expansions
|
||||||
|
(Proxmox-side disk grow → reboot → run role) are picked up
|
||||||
|
automatically.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Standalone:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- hosts: lincoln
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- expand_root_lv
|
||||||
|
```
|
||||||
|
|
||||||
|
Or chained ahead of an application role in a day1 playbook:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- hosts: honcho_server
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- expand_root_lv
|
||||||
|
- honcho
|
||||||
|
```
|
||||||
|
|
||||||
|
## Defaults
|
||||||
|
|
||||||
|
| Variable | Default | Purpose |
|
||||||
|
|-----------------------------------|---------------|---------------------------------------------------|
|
||||||
|
| `expand_root_lv_vg_name` | `ubuntu-vg` | LVM volume group name (Ubuntu installer default). |
|
||||||
|
| `expand_root_lv_lv_name` | `ubuntu-lv` | LVM logical volume name (Ubuntu installer default). |
|
||||||
|
| `expand_root_lv_mountpoint` | `/` | Mountpoint of the filesystem to grow. |
|
||||||
|
|
||||||
|
Override these in `host_vars/<host>.yml` for hosts that use a different
|
||||||
|
LVM layout. Hosts without LVM are silently no-op'd.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- Does not extend the underlying partition. If the operator grows the
|
||||||
|
Proxmox disk and the partition itself needs to grow before lvextend
|
||||||
|
can claim the new space, run `growpart /dev/sda 3` (or equivalent)
|
||||||
|
first. A future enhancement could automate this via `cloud-utils`'
|
||||||
|
`growpart` package, but it's out of scope for the initial template
|
||||||
|
fix-up case where the partition already covers the whole disk.
|
||||||
26
ansible/roles/expand_root_lv/defaults/main.yml
Normal file
26
ansible/roles/expand_root_lv/defaults/main.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
# ============================================================================
|
||||||
|
# expand-root-lv role defaults
|
||||||
|
# ============================================================================
|
||||||
|
# Extends the root LVM logical volume to fill its volume group, then grows
|
||||||
|
# the underlying filesystem to match. Idempotent: when there's no free PE
|
||||||
|
# in the VG (i.e. the LV already fills the VG), the lvextend step is a
|
||||||
|
# no-op and resize2fs/xfs_growfs simply confirms the filesystem is at
|
||||||
|
# capacity.
|
||||||
|
#
|
||||||
|
# Designed for Ubuntu cloud-image-style installations where the autoinstall
|
||||||
|
# template provisions an LV at half the disk size (the Ubuntu Server
|
||||||
|
# installer's longstanding default). Run once after VM provisioning to
|
||||||
|
# reclaim the unallocated PE; safe to leave in a day1 playbook so future
|
||||||
|
# disk expansions are picked up automatically.
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# The LV and VG names follow the Ubuntu Server installer's convention.
|
||||||
|
# Override per-host if your template differs.
|
||||||
|
expand_root_lv_vg_name: ubuntu-vg
|
||||||
|
expand_root_lv_lv_name: ubuntu-lv
|
||||||
|
|
||||||
|
# Mount point we expect to be backed by the target LV. Used purely for
|
||||||
|
# the resize2fs / xfs_growfs decision — the role inspects this path's
|
||||||
|
# filesystem type and dispatches to the correct grow command.
|
||||||
|
expand_root_lv_mountpoint: /
|
||||||
23
ansible/roles/expand_root_lv/meta/main.yml
Normal file
23
ansible/roles/expand_root_lv/meta/main.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
role_name: expand_root_lv
|
||||||
|
author: JARVIS
|
||||||
|
description: >-
|
||||||
|
Idempotent role that extends the root LVM logical volume to fill its
|
||||||
|
volume group and grows the underlying filesystem (ext4 or xfs). Fixes
|
||||||
|
the half-disk LV that the Ubuntu Server autoinstall template ships
|
||||||
|
with by default.
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.14"
|
||||||
|
platforms:
|
||||||
|
- name: Ubuntu
|
||||||
|
versions:
|
||||||
|
- noble
|
||||||
|
- jammy
|
||||||
|
galaxy_tags:
|
||||||
|
- lvm
|
||||||
|
- cloud-init
|
||||||
|
- homelab
|
||||||
|
- storage
|
||||||
|
|
||||||
|
dependencies: []
|
||||||
70
ansible/roles/expand_root_lv/tasks/main.yml
Normal file
70
ansible/roles/expand_root_lv/tasks/main.yml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
---
|
||||||
|
# ============================================================================
|
||||||
|
# expand-root-lv / main
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# 1. Confirm the target VG exists (skip role cleanly on non-LVM hosts).
|
||||||
|
# 2. Read free physical-extent count for the VG.
|
||||||
|
# 3. Extend the LV to +100%FREE only when free_pe > 0.
|
||||||
|
# 4. Grow the filesystem on the mountpoint (ext4 -> resize2fs, xfs -> xfs_growfs).
|
||||||
|
# Each step is idempotent and skips when there's nothing to do.
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
- name: Gather LVM facts
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "vgs --noheadings --nosuffix --units b -o vg_name,vg_free_count {{ expand_root_lv_vg_name }}"
|
||||||
|
register: vg_info
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Skip role when target VG is absent
|
||||||
|
ansible.builtin.meta: end_play
|
||||||
|
when: vg_info.rc != 0
|
||||||
|
|
||||||
|
- name: Parse free PE count
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
expand_root_lv_free_pe: "{{ (vg_info.stdout.split() | last | int) if vg_info.stdout | length > 0 else 0 }}"
|
||||||
|
|
||||||
|
- name: Extend LV to fill VG (only if free PE > 0)
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "lvextend -l +100%FREE /dev/{{ expand_root_lv_vg_name }}/{{ expand_root_lv_lv_name }}"
|
||||||
|
register: lvextend_result
|
||||||
|
when: expand_root_lv_free_pe | int > 0
|
||||||
|
changed_when: lvextend_result.rc == 0
|
||||||
|
|
||||||
|
- name: Detect filesystem type at mountpoint
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "findmnt {{ expand_root_lv_mountpoint }} -no FSTYPE"
|
||||||
|
register: fstype_result
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Set filesystem type fact
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
expand_root_lv_fstype: "{{ fstype_result.stdout | trim }}"
|
||||||
|
|
||||||
|
- name: Grow ext4 filesystem
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "resize2fs /dev/{{ expand_root_lv_vg_name }}/{{ expand_root_lv_lv_name }}"
|
||||||
|
register: resize_result
|
||||||
|
when:
|
||||||
|
- expand_root_lv_fstype == "ext4"
|
||||||
|
- lvextend_result.changed | default(false)
|
||||||
|
changed_when: resize_result.rc == 0
|
||||||
|
|
||||||
|
- name: Grow xfs filesystem
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "xfs_growfs {{ expand_root_lv_mountpoint }}"
|
||||||
|
register: xfs_result
|
||||||
|
when:
|
||||||
|
- expand_root_lv_fstype == "xfs"
|
||||||
|
- lvextend_result.changed | default(false)
|
||||||
|
changed_when: xfs_result.rc == 0
|
||||||
|
|
||||||
|
- name: Report current root size
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "df -h {{ expand_root_lv_mountpoint }}"
|
||||||
|
register: df_result
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Show post-resize disk usage
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "{{ df_result.stdout_lines }}"
|
||||||
Reference in New Issue
Block a user