Skip to content

Commit f75725c

Browse files
authored
Retry transient fresh LXC starts (#39)
Co-authored-by: Joseph Yaksich <gitcommit90@users.noreply.github.com>
1 parent 0169c7c commit f75725c

3 files changed

Lines changed: 27 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3232
bootstrap. A channel no longer repeatedly creates and cleans up its computer
3333
after starting `apt` during the guest-network race.
3434

35+
- A fresh channel now verifies and retries the same container when LXC's first
36+
daemonized start transiently loses its state-socket reply. The one-off
37+
`wait_on_daemonized_start` error no longer makes the channel appear broken
38+
while the automatic fleet pass successfully creates it moments later.
39+
3540
- 1Helm's narrow owned LXC forwarding rules are inserted ahead of host firewall
3641
policies such as Docker's `FORWARD=DROP`, allowing resident guests to reach
3742
package mirrors without replacing Docker or Tailscale chains.

scripts/1helm-lxc-runtime

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,28 @@ cpu_count() {
7878
printf '%s' "$total"
7979
}
8080
start() {
81-
[[ "$(state "$1")" == "RUNNING" ]] || lxc-start -P "$LXC_PATH" -n "$1" -d
82-
local attempt
83-
for attempt in {1..200}; do
84-
[[ "$(state "$1")" == "RUNNING" ]] && return
85-
sleep 0.1
81+
local name="$1" start_attempt state_attempt detail=""
82+
[[ "$(state "$name")" == "RUNNING" ]] && return
83+
# A freshly unpacked container can hit LXC's daemonized-start socket race:
84+
# lxc-start exits after wait_on_daemonized_start loses the state message even
85+
# though the container definition is intact and immediately startable. Check
86+
# the authoritative state after every invocation and retry that same exact
87+
# validated machine instead of failing channel creation on the transient.
88+
for start_attempt in {1..3}; do
89+
if ! detail="$(lxc-start -P "$LXC_PATH" -n "$name" -d 2>&1)"; then
90+
for state_attempt in {1..50}; do
91+
[[ "$(state "$name")" == "RUNNING" ]] && return
92+
sleep 0.1
93+
done
94+
continue
95+
fi
96+
for state_attempt in {1..200}; do
97+
[[ "$(state "$name")" == "RUNNING" ]] && return
98+
sleep 0.1
99+
done
86100
done
87-
die "container did not start"
101+
[[ -z "$detail" ]] || printf '%s\n' "$detail" >&2
102+
die "container did not start after 3 verified attempts"
88103
}
89104
wait_for_guest_network() {
90105
local name="$1" attempt

test/site.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ test("installer assets are explicit and syntax-valid", () => {
210210
assert.match(lxcHelper, /wait_for_guest_network[\s\S]*10\\\.0\\\.3\\\.[\s\S]*via 10\\\.0\\\.3\\\.1 dev eth0/, "fresh LXC provisioning waits for its DHCP address and default route");
211211
assert.match(lxcHelper, /archive\.ubuntu\.com[\s\S]*security\.ubuntu\.com[\s\S]*curl -4[\s\S]*InRelease/, "fresh LXC provisioning proves DNS and outbound IPv4 HTTP before package bootstrap");
212212
assert.match(lxcHelper, /start "\$name"[\s\S]*wait_for_guest_network "\$name"[\s\S]*apt-get update -o Acquire::ForceIPv4=true -o APT::Update::Error-Mode=any/, "package bootstrap begins only after bounded guest-network readiness");
213+
assert.match(lxcHelper, /for start_attempt in \{1\.\.3\}[\s\S]*lxc-start[\s\S]*state "\$name"[\s\S]*continue[\s\S]*container did not start after 3 verified attempts/, "a transient daemonized LXC state-socket failure is retried against the same validated machine");
213214
assert.match(lxcHelper, /cpuset\.cpus\.effective/, "LXC CPU limits are selected from the service's actually delegated host CPUs");
214215
assert.match(lxcHelper, /cpu_count/, "LXC inspection counts noncontiguous delegated CPU lists correctly");
215216
assert.match(lxcNetwork, /1helm-lxc-net-owned/, "the bridge wrapper stops only a bridge it started");

0 commit comments

Comments
 (0)