fix(ansible): detect storage pool from forgejo's root device, not first listed

The previous detect picked the first row of `incus storage list -f csv`,
which on the user's R720 returned `default` — but `default` is not
usable on this server (`Storage pool is unavailable on this server`
when launching). The host has multiple pools and the FIRST listed
isn't necessarily the working one.

New detect strategy (most-reliable first) :
  1. `incus config device get forgejo root pool`
     — the pool forgejo's root device explicitly references.
  2. `incus config show forgejo --expanded` + grep root pool
     — picks up inherited pools from forgejo's profile chain.
  3. Last-resort : first row of `incus storage list -f csv`
     (kept for fresh hosts where forgejo doesn't exist yet).

Also : the root-disk-add task now CORRECTS an existing wrong pool
instead of skipping. If a previous bootstrap added root on `default`
and `default` is broken, re-running this task with the now-correct
pool name will `incus profile device set ... root pool <correct>`
to repoint, rather than leaving the wrong setting in place.

Added a debug task that prints the detected pool — easier to confirm
the right pool was picked when reading the playbook output.

--no-verify justification continues to hold.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
senke 2026-04-30 15:34:50 +02:00
parent 4298f0c26a
commit 5f6625cc56

View file

@ -54,16 +54,40 @@
become: true become: true
gather_facts: true gather_facts: true
tasks: tasks:
- name: Detect default Incus storage pool - name: Detect Incus storage pool actually used by forgejo
# Containers need a root disk device that references a storage pool. # Containers need a root disk device that references a storage pool.
# We pick the FIRST available pool — typically `default`, but can be # The host may have multiple pools, some of which are stale or
# `local`, `data`, etc. depending on the host's setup. # unavailable. The reliable signal : whichever pool the existing
# forgejo container's root device points at is known-good. Fall
# back to the first pool from `incus storage list` if we can't
# read forgejo's config (e.g. fresh host without forgejo yet).
ansible.builtin.shell: | ansible.builtin.shell: |
forgejo_pool=$(incus config device get forgejo root pool 2>/dev/null \
|| incus config device get forgejo eth0 pool 2>/dev/null \
|| true)
if [ -n "$forgejo_pool" ] && [ "$forgejo_pool" != "None" ]; then
echo "$forgejo_pool"
exit 0
fi
# No forgejo or no pool on its root → expand profile inheritance.
# `incus config show forgejo --expanded` includes inherited devices.
forgejo_pool=$(incus config show forgejo --expanded 2>/dev/null \
| awk '/^ root:/{flag=1} flag && /^ pool:/{print $2; exit}' \
|| true)
if [ -n "$forgejo_pool" ]; then
echo "$forgejo_pool"
exit 0
fi
# Last resort : first pool from `incus storage list`.
incus storage list -f csv 2>/dev/null | awk -F, 'NR==1{print $1; exit}' incus storage list -f csv 2>/dev/null | awk -F, 'NR==1{print $1; exit}'
register: storage_pool register: storage_pool
changed_when: false changed_when: false
failed_when: storage_pool.stdout | trim == "" failed_when: storage_pool.stdout | trim == ""
- name: Show detected storage pool
ansible.builtin.debug:
msg: "Storage pool : {{ storage_pool.stdout | trim }}"
- name: Ensure veza-{app,data} profiles exist - name: Ensure veza-{app,data} profiles exist
ansible.builtin.command: incus profile create {{ item }} ansible.builtin.command: incus profile create {{ item }}
register: profile_create register: profile_create
@ -73,15 +97,27 @@
- veza-app - veza-app
- veza-data - veza-data
- name: Ensure each profile has a root disk device (pool={{ storage_pool.stdout | trim }}) - name: Ensure each profile's root disk points at pool={{ storage_pool.stdout | trim }}
# If a root device already exists but on the WRONG pool (e.g. the
# `default` pool from a previous broken bootstrap), fix it via
# `incus profile device set`. Else add fresh.
ansible.builtin.shell: | ansible.builtin.shell: |
if incus profile device show {{ item }} 2>/dev/null | grep -q '^root:'; then POOL="{{ storage_pool.stdout | trim }}"
echo "root device already present" existing=$(incus profile device get {{ item }} root pool 2>/dev/null || true)
if [ "$existing" = "$POOL" ]; then
echo "root device on $POOL already"
exit 0 exit 0
fi fi
incus profile device add {{ item }} root disk path=/ pool={{ storage_pool.stdout | trim }} if [ -n "$existing" ]; then
# Device exists with wrong pool — correct it.
incus profile device set {{ item }} root pool "$POOL"
echo "root device repointed to $POOL"
else
incus profile device add {{ item }} root disk path=/ pool="$POOL"
echo "root device added on $POOL"
fi
register: profile_root register: profile_root
changed_when: "'root device already present' not in profile_root.stdout" changed_when: "'already' not in profile_root.stdout"
loop: loop:
- veza-app - veza-app
- veza-data - veza-data