chore: apply all changes

This commit is contained in:
Hermes Agent service account
2026-09-01 12:28:16 -05:00
parent e9924a2524
commit 266b6c7be1
7 changed files with 157 additions and 17 deletions

View File

@@ -0,0 +1,22 @@
---
# Playbook: day3_deploy_qwen38_ctx131k.yml
# Purpose: Deploy Qwen3.8-27B-Q4_K_M ctx-size 65536 -> 131072 to astro-orbiter
# via llama-swap config re-render + restart.
#
# The git change to defaults/main.yml (line 235: ctx_size: 131072) is already staged.
# This playbook renders /etc/llama-swap/config.yaml from the updated defaults
# and restarts llama-swap to load the new ctx-size.
#
# Run:
# cd /home/hermes/git/homelab/ansible
# ansible-playbook -i inventory.yml playbooks/day3_deploy_qwen38_ctx131k.yml
#
- name: Deploy Qwen3.8 ctx-size 131072 to astro-orbiter
hosts: astro-orbiter
become: true
vars:
llm_swapmode_enabled: true
roles:
- role: llm-inference-multimodel
tags: [swapmode_config, swapmode_systemd, swapmode_verify]

View File

@@ -22,6 +22,7 @@ common_packages:
- net-tools
- dnsutils
- lvm2
- cloud-guest-utils
# ------------------------------------------------------------------------------
# LVM root volume expansion

View File

@@ -44,6 +44,15 @@ ExecStart={{ vllm_venv_path }}/bin/python -m vllm.entrypoints.openai.api_server
{% if item.enforce_eager is defined and item.enforce_eager %}
--enforce-eager \
{% endif %}
{% if item.enable_auto_tool_choice is defined and item.enable_auto_tool_choice %}
--enable-auto-tool-choice \
{% endif %}
{% if item.tool_call_parser is defined %}
--tool-call-parser {{ item.tool_call_parser }} \
{% endif %}
{% if item.reasoning_parser is defined %}
--reasoning-parser {{ item.reasoning_parser }} \
{% endif %}
{% if item.quantization is defined and item.quantization != 'none' %}
--quantization {{ item.quantization }} \
{% endif %}

View File

@@ -1,7 +1,8 @@
# 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).
Idempotent role that grows the root partition (via `growpart`), extends the
root LVM logical volume to fill its volume group, and grows the underlying
filesystem (ext4 or xfs).
## Where this runs in the lifecycle
@@ -24,6 +25,22 @@ size — a longstanding installer default that surprises every operator
who hasn't been bitten by it before. ~90% of mk-labs VMs need this
fix-up before they're fully useful.
After a Proxmox disk grow (increasing the VM disk size), the partition
table, physical volume, logical volume, and filesystem all need to be
extended in sequence. This role automates the full chain.
## Workflow
1. **growpart** — resizes the underlying partition to claim the newly
provisioned disk space. Idempotent: no-op when the partition already
fills the disk.
2. **pvresize** — tells the kernel/LVM about the new partition size so
the VG sees the additional free PEs.
3. **lvextend** — extends the LV to claim all free PE in the VG
(`+100%FREE`). No-op when there's nothing to grow.
4. **fs grow**`resize2fs` (ext4) or `xfs_growfs` (xfs), dispatched by
detected filesystem type.
## Idempotency
- If `vg_free_count == 0`, the `lvextend` step is skipped and the
@@ -49,22 +66,30 @@ expand_root_lv_skip: true
The day0 playbook checks this flag and skips the role cleanly.
To skip only the partition growstep while keeping LV/FS expansion
(e.g. when the partition already covers the whole disk but the LV was
provisioned small by the template), set:
```yaml
expand_root_lv_pv_partition: undefined
```
## 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_pv_partition` | `/dev/sda3` | Partition backing the PV; grown via growpart. |
| `expand_root_lv_mountpoint` | `/` | Mountpoint of the filesystem to grow. |
Override the VG/LV names in `host_vars/<host>.yml` for hosts that use a
different LVM layout.
Override the VG/LV/PV names in `host_vars/<host>.yml` for hosts that use a
different layout.
## 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.
- The `growpart` step requires the `cloud-guest-utils` package. The role
installs it automatically on Debian/Ubuntu hosts when
`expand_root_lv_pv_partition` is defined.
- Only supports ext4 and xfs filesystems. Other filesystem types (btrfs,
etc.) are left as a future enhancement.

View File

@@ -20,6 +20,12 @@
expand_root_lv_vg_name: ubuntu-vg
expand_root_lv_lv_name: ubuntu-lv
# The partition that backs the physical volume. After a Proxmox disk grow,
# growpart must resize this partition before pvresize/lvextend can claim
# the new space. This is the full device path (e.g. /dev/sda3).
# If undefined, the growpart/pvresize steps are skipped.
expand_root_lv_pv_partition: /dev/sda3
# 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.

View File

@@ -2,44 +2,108 @@
# ============================================================================
# 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).
# 0. Ensure growpart is available (cloud-guest-utils provides the growpart binary)
# 1. Grow the partition (growpart) if a PV partition device is defined
# 2. Resize the physical volume (pvresize) to pick up the new partition size
# 3. Confirm the target VG exists (skip role cleanly on non-LVM hosts).
# 4. Read free physical-extent count for the VG.
# 5. Extend the LV to +100%FREE only when free_pe > 0.
# 6. Grow the filesystem on the mountpoint (ext4 -> resize2fs, xfs -> xfs_growfs).
# Each step is idempotent and skips when there's nothing to do.
# ============================================================================
# ---------------------------------------------------------------------------
# Step 0: Ensure growpart is available
# ---------------------------------------------------------------------------
- name: Ensure cloud-guest-utils (growpart) is installed
ansible.builtin.package:
name: cloud-guest-utils
state: present
when: expand_root_lv_pv_partition is defined
tags: [growpart, always]
# ---------------------------------------------------------------------------
# Step 1: Grow the partition that backs the PV
# ---------------------------------------------------------------------------
# growpart expects: growpart <device> <partition_number>
# e.g. growpart /dev/sda 3 — NOT growpart /dev/sda3
# We split expand_root_lv_pv_partition (e.g. /dev/sda3) into device and part_no.
- name: Derive device and partition number from PV partition path
ansible.builtin.set_fact:
expand_root_lv_pv_device: "{{ expand_root_lv_pv_partition | regex_replace('p?(\\d+)$', '') }}"
expand_root_lv_pv_part_no: "{{ expand_root_lv_pv_partition | regex_replace('.*p?(\\d+)$', '\\1') }}"
when: expand_root_lv_pv_partition is defined
tags: [growpart, always]
- name: Grow partition to fill disk (growpart)
ansible.builtin.command:
cmd: "growpart {{ expand_root_lv_pv_device }} {{ expand_root_lv_pv_part_no }}"
register: growpart_result
when: expand_root_lv_pv_partition is defined
changed_when: growpart_result.rc == 0 and "NO CHANGE" not in growpart_result.stdout
tags: [growpart, always]
# ---------------------------------------------------------------------------
# Step 2: Resize the physical volume to claim the new partition space
# ---------------------------------------------------------------------------
- name: Resize physical volume (pvresize)
ansible.builtin.command:
cmd: "pvresize {{ expand_root_lv_pv_partition }}"
register: pvresize_result
when: expand_root_lv_pv_partition is defined
changed_when: pvresize_result.rc == 0
tags: [pvresize, always]
# ---------------------------------------------------------------------------
# Step 3: Confirm the target VG exists (skip role cleanly on non-LVM hosts).
# ---------------------------------------------------------------------------
- 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
tags: [lvm, always]
- name: Skip role when target VG is absent
ansible.builtin.meta: end_play
when: vg_info.rc != 0
tags: [lvm, always]
# ---------------------------------------------------------------------------
# Step 4: Parse free PE count for the VG
# ---------------------------------------------------------------------------
- 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 }}"
tags: [lvm, always]
# ---------------------------------------------------------------------------
# Step 5: Extend the LV to +100%FREE only when free_pe > 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
tags: [lvm, always]
# ---------------------------------------------------------------------------
# Step 6: Detect filesystem type at mountpoint and grow
# ---------------------------------------------------------------------------
- name: Detect filesystem type at mountpoint
ansible.builtin.command:
cmd: "findmnt {{ expand_root_lv_mountpoint }} -no FSTYPE"
register: fstype_result
changed_when: false
tags: [filesystem, always]
- name: Set filesystem type fact
ansible.builtin.set_fact:
expand_root_lv_fstype: "{{ fstype_result.stdout | trim }}"
tags: [filesystem, always]
- name: Grow ext4 filesystem
ansible.builtin.command:
@@ -47,8 +111,12 @@
register: resize_result
when:
- expand_root_lv_fstype == "ext4"
- lvextend_result.changed | default(false)
- (growpart_result is defined and growpart_result.changed) or
(pvresize_result is defined and pvresize_result.changed) or
(lvextend_result is defined and lvextend_result.changed) or
(growpart_result is not defined)
changed_when: resize_result.rc == 0
tags: [filesystem, always]
- name: Grow xfs filesystem
ansible.builtin.command:
@@ -56,15 +124,24 @@
register: xfs_result
when:
- expand_root_lv_fstype == "xfs"
- lvextend_result.changed | default(false)
- (growpart_result is defined and growpart_result.changed) or
(pvresize_result is defined and pvresize_result.changed) or
(lvextend_result is defined and lvextend_result.changed) or
(growpart_result is not defined)
changed_when: xfs_result.rc == 0
tags: [filesystem, always]
# ---------------------------------------------------------------------------
# Step 7: Report current root size
# ---------------------------------------------------------------------------
- name: Report current root size
ansible.builtin.command:
cmd: "df -h {{ expand_root_lv_mountpoint }}"
register: df_result
changed_when: false
tags: [always]
- name: Show post-resize disk usage
ansible.builtin.debug:
msg: "{{ df_result.stdout_lines }}"
tags: [always]

View File

@@ -232,7 +232,7 @@ llm_swapmode_models:
gguf_path: "{{ llm_models_dir }}/Qwen3.8-27B-Q4_K_M.gguf"
port: 8105
n_gpu_layers: -1 # -1 = auto-detect / all layers to GPU
ctx_size: 65536
ctx_size: 131072 # t_ca3ff615: 65536 -> 131072 (VRAM pre-validated ~20.3GB < 24GB, t_441470b9)
batch_size: 4096
ubatch_size: 4096
parallel: 1