Skip to content

Loadbalancer reboot never routes through the stage-3c bridge, so it can create the new volume before it is copied #168

Description

@mhenrixon

Problem

Dash::Cli::Proxy::LoadbalancerReboot#run (used by both dash proxy reboot and the
drift-detected reboot inside dash proxy boot) calls DASH.loadbalancer.run directly,
without ever invoking the stage-3c bridge (Dash::Commands::Loadbalancer#legacy_rename /
#prepare_boot, added in #167). Dash::Cli::Proxy::Reboot (the per-host proxy equivalent)
has the same gap.

docker run --volume dash-loadbalancer-config:... auto-creates the named volume if it
doesn't exist yet, empty. If an operator runs dash proxy reboot against a dedicated
load-balancer host that has never been through dash proxy boot, this creates
dash-loadbalancer-config fresh and empty - before the bridge has ever had a chance to
copy kamal-loadbalancer-config's routing table and ACME cache into it.

The next dash proxy boot on that host then finds dash-loadbalancer-config already
existing and skips the copy (via copy_legacy_config_volume's own guard, unchanged by
#167) - the legacy state is never adopted, silently. This predates #167: on main today,
the same guard already causes this every deploy, forever, without a marker.

#167 added a persistent marker (.legacy-renamed) that short-circuits the whole bridge
once written. Given the volume-existence guard above, the marker gets written in this
exact scenario too - turning what was already a silent, permanent skip into one that
additionally requires deleting the marker file (not just fixing the volume) to recover.
See the comment on Dash::Commands::Loadbalancer#mark_legacy_renamed for the full
analysis (from PR #167's review).

Fix

Route Dash::Cli::Proxy::LoadbalancerReboot#run and Dash::Cli::Proxy::Reboot#run
through the same bridge (prepare_boot/legacy_rename) before anything that could
create the new container, volume or network - closing the gap at its source instead of
trying to make the marker's heuristic smarter. This adds a round trip to reboot that it
doesn't pay today; that's an acceptable trade against the correctness gap, but is why this
is a separate PR rather than folded into #167 (scoped to boot's round trips only, per
the original issue #160).

Out of scope here

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    gemdash gem (Ruby) work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions