fix(relocate): guard against from/to resolving to the same machine #53

Merged
traveler merged 1 commit from gremlin/relocate-safety-fixes into main 2026-07-27 13:30:16 -05:00 AGit
Contributor

Found via live testing 2026-07-27, immediately after merging #51:
pocket and grimoire currently resolve back to znas itself (Caddy
DNS, documented gotcha in reference_znas_ssh memory) since the real
multi-host road topology isn't up yet. Without a same-machine guard,
a relocate targeting "pocket" today would silently deploy the "target"
on the SAME docker engine as the source, then tear the source down
once "target" reports healthy -- net result: the service ends up torn
down entirely, not relocated, while every log entry says "ok".

Added a machine-id comparison (harder guarantee than hostname, which
could theoretically collide) as the second precheck step, right after
basic reachability. Confirmed live: a same-host test now fails cleanly
at this new check instead of proceeding.

Also fixes a second bug from the same test run: the DockerVol
parity check treated every stack as if it must have a DockerVol/
directory. 5 of 14 (stash, it-tools, nettools, kiwix, devdocs) are
either stateless or use green instead, so that directory legitimately
never exists for them -- the check now only runs for stacks whose
compose file actually references DockerVol/.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01QZCa7HKzyLGzs8qsD3Y5i1

Found via live testing 2026-07-27, immediately after merging #51: `pocket` and `grimoire` currently resolve back to znas itself (Caddy DNS, documented gotcha in reference_znas_ssh memory) since the real multi-host road topology isn't up yet. Without a same-machine guard, a relocate targeting "pocket" today would silently deploy the "target" on the SAME docker engine as the source, then tear the source down once "target" reports healthy -- net result: the service ends up torn down entirely, not relocated, while every log entry says "ok". Added a machine-id comparison (harder guarantee than hostname, which could theoretically collide) as the second precheck step, right after basic reachability. Confirmed live: a same-host test now fails cleanly at this new check instead of proceeding. Also fixes a second bug from the same test run: the DockerVol parity check treated every stack as if it must have a DockerVol/<name> directory. 5 of 14 (stash, it-tools, nettools, kiwix, devdocs) are either stateless or use `green` instead, so that directory legitimately never exists for them -- the check now only runs for stacks whose compose file actually references DockerVol/<name>. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QZCa7HKzyLGzs8qsD3Y5i1
Found via live testing 2026-07-27, immediately after merging #51:
`pocket` and `grimoire` currently resolve back to znas itself (Caddy
DNS, documented gotcha in reference_znas_ssh memory) since the real
multi-host road topology isn't up yet. Without a same-machine guard,
a relocate targeting "pocket" today would silently deploy the "target"
on the SAME docker engine as the source, then tear the source down
once "target" reports healthy -- net result: the service ends up torn
down entirely, not relocated, while every log entry says "ok".

Added a machine-id comparison (harder guarantee than hostname, which
could theoretically collide) as the second precheck step, right after
basic reachability. Confirmed live: a same-host test now fails cleanly
at this new check instead of proceeding.

Also fixes a second bug from the same test run: the DockerVol
parity check treated every stack as if it must have a DockerVol/<name>
directory. 5 of 14 (stash, it-tools, nettools, kiwix, devdocs) are
either stateless or use `green` instead, so that directory legitimately
never exists for them -- the check now only runs for stacks whose
compose file actually references DockerVol/<name>.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QZCa7HKzyLGzs8qsD3Y5i1
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
traveler/pocket!53
No description provided.