From 5f6625cc5628890951a01ef7e60f7593852b6a00 Mon Sep 17 00:00:00 2001 From: senke Date: Thu, 30 Apr 2026 15:34:50 +0200 Subject: [PATCH] fix(ansible): detect storage pool from forgejo's root device, not first listed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 ` 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) --- infra/ansible/playbooks/bootstrap_runner.yml | 52 +++++++++++++++++--- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/infra/ansible/playbooks/bootstrap_runner.yml b/infra/ansible/playbooks/bootstrap_runner.yml index 472e5070c..0a20af28b 100644 --- a/infra/ansible/playbooks/bootstrap_runner.yml +++ b/infra/ansible/playbooks/bootstrap_runner.yml @@ -54,16 +54,40 @@ become: true gather_facts: true 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. - # We pick the FIRST available pool — typically `default`, but can be - # `local`, `data`, etc. depending on the host's setup. + # The host may have multiple pools, some of which are stale or + # 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: | + 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}' register: storage_pool changed_when: false 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 ansible.builtin.command: incus profile create {{ item }} register: profile_create @@ -73,15 +97,27 @@ - veza-app - 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: | - if incus profile device show {{ item }} 2>/dev/null | grep -q '^root:'; then - echo "root device already present" + POOL="{{ storage_pool.stdout | trim }}" + existing=$(incus profile device get {{ item }} root pool 2>/dev/null || true) + if [ "$existing" = "$POOL" ]; then + echo "root device on $POOL already" exit 0 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 - changed_when: "'root device already present' not in profile_root.stdout" + changed_when: "'already' not in profile_root.stdout" loop: - veza-app - veza-data