Skip to content

Commit 49bdad8

Browse files
committed
Harden Incus storage parsing and restart checks
Force `LC_ALL=C` for `incus storage info/get` so storage fields are parsed reliably on non-English hosts, and add a `df` fallback for `dir` pools when Incus reports no free space. Also improve UX by showing `Free: unknown` instead of `~?GB`, and fail fast if container restart leaves it stopped so later `incus exec` steps do not cascade into misleading errors.
1 parent 7ed5d67 commit 49bdad8

1 file changed

Lines changed: 28 additions & 5 deletions

File tree

incus/backend.func

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,18 @@ incus_storage_pool_free_gb() {
125125
local info free_bytes total_bytes used_bytes free_raw total_raw used_raw
126126

127127
# Prefer machine-readable bytes when available (Incus --bytes).
128-
info=$(incus storage info --bytes "$pool" 2>/dev/null || true)
128+
# LC_ALL=C: incus translates this output. A German host reports "Gesamter
129+
# Speicherplatz" and "Speicherplatz in Benutzung", so the awk below matched
130+
# nothing and a 357GB pool looked unmeasurable.
131+
info=$(LC_ALL=C incus storage info --bytes "$pool" 2>/dev/null || true)
129132
free_raw=$(echo "$info" | awk -F': *' '/space free:/ {print $2; exit}')
130133
if [[ -n "$free_raw" ]]; then
131134
free_bytes="$(_incus_parse_size_to_bytes "$free_raw" 2>/dev/null || true)"
132135
fi
133136

134137
# Older/human output often has only "space used" + "total space" (no free line).
135138
if [[ -z "${free_bytes:-}" ]]; then
136-
info=$(incus storage info "$pool" 2>/dev/null || true)
139+
info=$(LC_ALL=C incus storage info "$pool" 2>/dev/null || true)
137140
free_raw=$(echo "$info" | awk -F': *' '/space free:/ {print $2; exit}')
138141
total_raw=$(echo "$info" | awk -F': *' '/total space:/ {print $2; exit}')
139142
used_raw=$(echo "$info" | awk -F': *' '/space used:/ {print $2; exit}')
@@ -148,6 +151,16 @@ incus_storage_pool_free_gb() {
148151
fi
149152
fi
150153

154+
# A dir pool is just a path, so ask the filesystem when incus says nothing.
155+
# Does not help lvm or zfs, where source is not a path.
156+
if [[ -z "${free_bytes:-}" ]]; then
157+
local src
158+
src="$(LC_ALL=C incus storage get "$pool" source 2>/dev/null || true)"
159+
if [[ -n "$src" && -d "$src" ]]; then
160+
free_bytes="$(df -PB1 "$src" 2>/dev/null | awk 'NR==2 {print $4}')"
161+
fi
162+
fi
163+
151164
[[ -z "${free_bytes:-}" || "$free_bytes" -le 0 ]] && return 1
152165
echo $((free_bytes / 1024 / 1024 / 1024))
153166
}
@@ -178,8 +191,13 @@ resolve_storage_preselect() {
178191
incus storage info "$preselect" &>/dev/null || return 1
179192
STORAGE_RESULT="$preselect"
180193
local free_gb
181-
free_gb=$(incus_storage_pool_free_gb "$preselect" 2>/dev/null || echo "?")
182-
STORAGE_INFO="Free: ~${free_gb}GB"
194+
free_gb=$(incus_storage_pool_free_gb "$preselect" 2>/dev/null || true)
195+
# "Free: ~?GB" reads like a broken template. Say what is actually known.
196+
if [[ -n "$free_gb" ]]; then
197+
STORAGE_INFO="Free: ~${free_gb}GB"
198+
else
199+
STORAGE_INFO="Free: unknown"
200+
fi
183201
return 0
184202
}
185203

@@ -474,7 +492,12 @@ incus_create_lxc_container() {
474492
msg_ok "Container configuration verified"
475493
fi
476494
else
477-
msg_warn "Container restart failed after configuration changes"
495+
# Everything past this point needs incus exec. Warning and carrying on
496+
# over a stopped container is what turned one failed restart into three
497+
# unrelated-looking errors further down.
498+
msg_error "Container ${CT_NAME} is not running after configuration changes"
499+
msg_custom "ℹ️" "${YW}" "See: incus info --show-log ${CT_NAME}"
500+
return 1
478501
fi
479502
fi
480503
}

0 commit comments

Comments
 (0)