plans: row 87 round 7 makes the leftover rule wait by id until each core container is gone and names the start order (#1581)
Answers Darkwing's round 6 review (28884) and Filbert's doc-only follow-up (28883). - After docker stop, the rule waits for "no such container" by id, bounded by the core stop timeout, then rm -f and the same wait; a container still there refuses exit 1, which the unit retries. - A name conflict is now only a hand-made container without the store's labels; it stays exit 3, which the unit does not retry. - Start order: host.lock, store path, rootless check, leftover rule, docker run. - I6 gains two tests: run straight after a stop boots, and a leftover never removed refuses exit 1. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -9,7 +9,9 @@ answers their round 2 reviews (Darkwing 28863, Filbert 28864). Round 4
|
||||
answers their round 3 reviews (Darkwing 28871, Filbert 28870). Round 5
|
||||
answers Darkwing's round 4 review (28877) and Filbert's doc-only
|
||||
follow-up on the stop timeout (28876). Round 6 answers Darkwing's round
|
||||
5 review (28880) and Filbert's doc-only follow-ups (28881).
|
||||
5 review (28880) and Filbert's doc-only follow-ups (28881). Round 7
|
||||
answers Darkwing's round 6 review (28884) and Filbert's doc-only
|
||||
follow-up on the start order (28883).
|
||||
|
||||
This doc turns decisions 105 to 108 into interfaces. It doesn't reopen
|
||||
them. Every claim about container behavior cites a spike in
|
||||
@@ -151,8 +153,11 @@ fork's exit code (`host.mjs:341-347`), and the start failure path kills
|
||||
the notifier alone (`host.mjs:252-257`). Containerized mode keeps all of
|
||||
that by putting each fork's events on the channel.
|
||||
|
||||
- **The store path.** Before anything else touches the engine, bus
|
||||
start makes `<dataRoot>/bus` if it is missing, mode 0700, the way the
|
||||
- **The start order.** Bus start takes `host.lock`, then sets the store
|
||||
path, then runs the rootless check (section 4) before the leftover
|
||||
rule's first engine call, then the leftover rule, then `docker run`.
|
||||
- **The store path.** Right after `host.lock`, bus start makes
|
||||
`<dataRoot>/bus` if it is missing, mode 0700, the way the
|
||||
broker's `Store` does today (`packages/bus/src/store.mjs:126`), which
|
||||
only the broker does now. The host makes only `bus-host/`
|
||||
(`host.mjs:80`, `:120`), so on a fresh install nothing else would. Bus
|
||||
@@ -175,9 +180,13 @@ that by putting each fork's events on the channel.
|
||||
store while one exists in any state. The host reads the forks' exit
|
||||
codes from the channel, not from the container, so `--rm` loses
|
||||
nothing it reads.
|
||||
- **A name conflict.** The leftover rule below runs first, so a conflict
|
||||
means a container with the name appeared after the list, or one the
|
||||
engine is still removing. The `docker run` client then exits before
|
||||
- **A name conflict.** The leftover rule below runs first and waits
|
||||
until every container it listed is gone, so a conflict means a
|
||||
container holds the name without the store's labels, which only a
|
||||
hand-made container would. That needs the operator, so the refusal
|
||||
is exit 3, which the unit doesn't retry
|
||||
(`packages/cli/systemd/mosaic-bus.service.in:33`). The `docker run`
|
||||
client then exits before
|
||||
any line, and the engine's error goes to the host log through the
|
||||
client's inherited stderr. The host doesn't parse that text. Bus start
|
||||
refuses with exit 3, `core container mosaic-core-<store hash> did not
|
||||
@@ -267,9 +276,18 @@ that by putting each fork's events on the channel.
|
||||
core container starts, bus start lists containers labelled
|
||||
`mosaic.kind=core` and `mosaic.store=<store path>` through the
|
||||
endpoint helper. It runs `docker stop -t <core stop timeout>` on each,
|
||||
45 s at today's value, which covers both of the entry's close waits,
|
||||
then `docker rm -f` on any that `--rm` hasn't removed, and logs each to
|
||||
the host log. `host.lock` is held, so no live host owns a leftover. A
|
||||
45 s at today's value, which covers both of the entry's close waits.
|
||||
`--rm` removes a container after `stop` returns, and `docker rm -f`
|
||||
during that removal errors instead of waiting, so the rule then waits
|
||||
until each listed container is gone, by id, bounded by the core stop
|
||||
timeout. Gone means the endpoint answers "no such container" for that
|
||||
id. A container still there at the bound gets `docker rm -f` and the
|
||||
same bounded wait. One still there after that makes bus start refuse
|
||||
with exit 1, `leftover core container <id> not removed`, which the
|
||||
unit retries after `RestartSec`, since an engine still removing is a
|
||||
passing state. Each step goes to the host log. `docker run` starts
|
||||
only once every listed container is gone. `host.lock` is held, so no
|
||||
live host owns a leftover. A
|
||||
leftover that stopped on SIGTERM has removed `writer.lock`. One that
|
||||
`rm -f` killed leaves it, and the start refuses `writer-locked`, as it
|
||||
does today after a broker dies hard. The lock is an exclusive create in
|
||||
|
||||
@@ -486,6 +486,10 @@ and no document states the limits in design section 10.
|
||||
bus start;
|
||||
- on a fresh data root, bus start makes `<dataRoot>/bus` at 0700
|
||||
before it resolves the store path;
|
||||
- `docker run` straight after a leftover's stop boots without a name
|
||||
conflict: the rule waits until the stopped container is gone;
|
||||
- a leftover that is never removed in the bound makes bus start
|
||||
refuse with exit 1 and log its id;
|
||||
- a container that already holds the core name but not the store's
|
||||
labels makes bus start refuse with exit 3 and the message naming
|
||||
the name and the client's exit code; `host.lock` is given back,
|
||||
|
||||
Reference in New Issue
Block a user