Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/verify-split-files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ on:
- "tests/incus-target.sh"
- "tests/incus-storage-space.sh"
- "tests/release-stamp-pending.sh"
- "tests/pct-start-reason.sh"
- ".github/workflows/verify-split-files.yml"
push:
branches: [main]
Expand Down Expand Up @@ -69,6 +70,7 @@ on:
- "tests/incus-target.sh"
- "tests/incus-storage-space.sh"
- "tests/release-stamp-pending.sh"
- "tests/pct-start-reason.sh"
- ".github/workflows/verify-split-files.yml"
workflow_dispatch:

Expand Down Expand Up @@ -139,6 +141,8 @@ jobs:
run: bash tests/incus-storage-space.sh
- name: Release stamp pending marker tests
run: bash tests/release-stamp-pending.sh
- name: pct start reason tests
run: bash tests/pct-start-reason.sh

- name: Prefetch lists cover every engine file
run: |
Expand Down
5 changes: 3 additions & 2 deletions pve/backend.func
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ _pct_start_failed() {
reason="$(journalctl -u "pve-container@${ctid}" -n 80 --no-pager -o cat 2>/dev/null |
awk '/^Starting pve-container@/ { n = 0; next } { l[++n] = $0 } END { for (i = 1; i <= n; i++) print l[i] }' |
grep -vE '^pve-container@[0-9]+\.service: |^Failed to start pve-container@|To get more details, run the container in foreground mode' |
tail -n 10)"
tail -n 10 || true)"
{
echo "--- pct start ${ctid} ---"
[[ -n "$out" ]] && echo "$out"
Expand Down Expand Up @@ -3591,7 +3591,8 @@ create_lxc_container() {
# - Posts final "done" status to API telemetry
# ------------------------------------------------------------------------------
description() {
IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
IP=$(pct exec "$CTID" -- ip -4 addr show dev eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1 || true)
[[ -n "$IP" ]] || IP=$(pct exec "$CTID" -- ip -6 addr show dev eth0 scope global 2>/dev/null | awk '/inet6 / {print $2}' | cut -d/ -f1 | head -n1 || true)

# Links follow the repository the script actually came from, which
# detect_repo_source() has already established. Hardcoding DevScripts sent
Expand Down
59 changes: 59 additions & 0 deletions tests/pct-start-reason.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# _pct_start_failed runs under the host's errexit and ERR trap. Its journal
# filter ends in grep -v, which exits 1 when nothing survives, so the helper
# that explains a failed start was itself reported as the failure.
set -uo pipefail

CORE_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
eval "$(awk '/^_pct_start_failed[(][)] [{]/,/^}/' "$CORE_DIR/pve/backend.func")"

TEST_DIR="$(mktemp -d)"
trap 'rm -rf -- "$TEST_DIR"' EXIT
export TAB=" " YW="" CL=""
BUILD_LOG="$TEST_DIR/build.log"
JOURNAL="$TEST_DIR/journal"
: >"$JOURNAL"
passed=0 failed=0

journalctl() { cat "$JOURNAL"; }
msg_custom() { :; }

expect() {
if [[ "$2" == "$3" ]]; then
echo "PASS $1"
passed=$((passed + 1))
else
echo "FAIL $1: expected <$2>, got <$3>" >&2
failed=$((failed + 1))
fi
}

# The helper as the host runs it: errexit, errtrace, pipefail and an ERR trap.
run_helper() {
(
set -Eeo pipefail
trap 'echo TRAPPED; exit 99' ERR
_pct_start_failed 100 "$1"
echo "rc=$?"
) 2>&1
}

out="$(run_helper "startup for container '100' failed")"
expect "an empty journal does not trip the ERR trap" 0 "$(grep -c TRAPPED <<<"$out")"
expect "the helper returns 0" 1 "$(grep -c '^rc=0$' <<<"$out")"
expect "the pct output is shown instead" 1 "$(grep -c "startup for container" <<<"$out")"
expect "the build log gets the pct output" 1 "$(grep -c "startup for container" "$BUILD_LOG")"

: >"$BUILD_LOG"
printf '%s\n' 'Starting pve-container@100.service - PVE LXC Container: 100...' \
'lxc-start: 100: conf.c: mount_entry: No such file or directory' \
'pve-container@100.service: Control process exited, code=exited, status=1/FAILURE' \
'Failed to start pve-container@100.service - PVE LXC Container: 100.' >"$JOURNAL"
out="$(run_helper "pct out")"
expect "the journal reason survives the filter" 1 "$(grep -c 'conf.c: mount_entry' <<<"$out")"
expect "systemd bookkeeping is dropped" 0 "$(grep -c 'Control process exited' <<<"$out")"
expect "a journal with lines does not trip the trap either" 0 "$(grep -c TRAPPED <<<"$out")"
expect "the reason lands in the build log" 1 "$(grep -c 'conf.c: mount_entry' "$BUILD_LOG")"

echo "$passed passed, $failed failed"
((failed == 0))
Loading