Commit 22609f7
fix: check the release record in the call that acts on it
upgradable/0 was a gate bin/castle asked for in an rpc of its own,
before the rpc that unpacked or installed. Two rpcs are two moments and
possibly two node instances: a node could answer on the strength of the
record it read at boot, restart before the second call arrived, and
synthesise an empty record on the way back up - and the unpack or the
install would then go ahead on an answer that no longer held, which is
the silent stale-code failure the gate exists to prevent. A check whose
answer can be invalidated between asking and acting is not a check.
So Commands.unpack/2 and Commands.install/2 make it themselves, before
:release_handler is asked for anything. One call, one record, one
decision, and nothing to reintroduce in the shell.
install is checked because that is where the damage is. unpack is
checked because it is the one other operation that writes release
records: do_unpack_release/4 ends in write_releases/3 over the records
the handler holds, so an unpack on such a node puts the synthesised
record into RELEASES, the next boot reads it back, and make_releases/2
does nothing when the file is there - which takes away the restart the
refusal names as the remedy and leaves the system with no way out.
commit, remove and releases stay unchecked, and that is measured rather
than assumed: do_make_permanent/2 returns early for a release that is
already permanent and errors for every other status,
do_remove_release/4 refuses the permanent release outright, and
releases only reads, so none of them can write that record back, while
refusing them could strand a version already installed and waiting to
be committed.
The refusal now names the operation that did not happen rather than
reading as a precondition an operator failed to satisfy: "Cannot
install 1.2.3: 1.2.2 is running from a release record OTP built from
the boot script ...".
upgradable/0 stays, as a query rather than a gate. Nothing has to call
it, but the state it reports is invisible otherwise - the file can be
present while the record the node works from was synthesised - so an
operator needs some way to ask that does not unpack or install
anything. Whether it belongs in the documented API surface is #11's.
The new tests are about ordering, so they are written the way
materialise/2's are: the stub is handed a reply that would have the
operation succeed and the assertion is that it was never asked for it,
because the refusal looks the same whether it came before the mutation
or after. Two more assert which_releases was called in the call that
acted, which no version asking it elsewhere can pass, and commit's
guard is the mirror image - a synthesised record, and which_releases
never called.
Forecastle drops the separate upgradable rpc from bin/castle: nothing
replaces it, because the operations refuse for themselves.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C4oaMvbR1cbxrZBj8qwkqN1 parent 5c5e9e0 commit 22609f7
6 files changed
Lines changed: 312 additions & 83 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
284 | 284 | | |
285 | 285 | | |
286 | 286 | | |
287 | | - | |
288 | | - | |
289 | | - | |
290 | | - | |
291 | | - | |
292 | | - | |
293 | | - | |
294 | | - | |
295 | | - | |
296 | | - | |
297 | | - | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
298 | 298 | | |
299 | 299 | | |
300 | 300 | | |
301 | | - | |
302 | | - | |
303 | | - | |
304 | | - | |
305 | | - | |
306 | | - | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
307 | 335 | | |
308 | 336 | | |
309 | | - | |
310 | | - | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
311 | 346 | | |
312 | 347 | | |
313 | 348 | | |
| |||
394 | 429 | | |
395 | 430 | | |
396 | 431 | | |
397 | | - | |
398 | | - | |
| 432 | + | |
| 433 | + | |
399 | 434 | | |
400 | 435 | | |
401 | | - | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
402 | 450 | | |
403 | 451 | | |
404 | 452 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
61 | 80 | | |
62 | 81 | | |
63 | 82 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
29 | 36 | | |
30 | 37 | | |
31 | 38 | | |
| |||
58 | 65 | | |
59 | 66 | | |
60 | 67 | | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
66 | 84 | | |
67 | 85 | | |
68 | 86 | | |
| |||
0 commit comments