Skip to content

Only ensure the run directory on the primary host#1908

Open
andyjeffries wants to merge 1 commit into
basecamp:mainfrom
andyjeffries:ensure-run-directory-on-primary-host
Open

Only ensure the run directory on the primary host#1908
andyjeffries wants to merge 1 commit into
basecamp:mainfrom
andyjeffries:ensure-run-directory-on-primary-host

Conversation

@andyjeffries

Copy link
Copy Markdown

Every command that takes the deploy lock first runs mkdir -p of the run directory (.kamal) on all configured hosts, via ensure_run_directory. But the run directory only needs to exist where something actually reads or writes it, and the only consumer that depends on this preamble is the deploy lock, which is acquired and released solely on the primary host.

This is most visible on single-host operations such as kamal accessory reboot <name>: rebooting an accessory pinned to one host still opens an SSH connection to every server in the deploy just to create an empty .kamal directory it never uses.

ensure_run_directory has exactly two callers -- acquire_lock and Lock#acquire -- and in both it is only a precondition for the lock. The lock's directory is created with a plain, non--p mkdir (an atomic lock primitive), so its parent must pre-exist; that is the whole reason for the preamble. Since the lock lives only on the primary host, the run directory only needs pre-creating there.

Everything else under the run directory self-creates with mkdir -p on the hosts where it runs: env files and secrets
(app/accessory.ensure_env_directory), proxy config, and the audit log (Auditor#record prepends its own mkdir -p). None of them rely on this preamble, so narrowing it to the primary host changes no other behaviour.

Every command that takes the deploy lock first runs `mkdir -p` of the
run directory (`.kamal`) on *all* configured hosts, via
`ensure_run_directory`. But the run directory only needs to exist where
something actually reads or writes it, and the only consumer that
depends on this preamble is the deploy lock, which is acquired and
released solely on the primary host.

This is most visible on single-host operations such as
`kamal accessory reboot <name>`: rebooting an accessory pinned to one
host still opens an SSH connection to every server in the deploy just
to create an empty `.kamal` directory it never uses.

`ensure_run_directory` has exactly two callers -- `acquire_lock` and
`Lock#acquire` -- and in both it is only a precondition for the lock.
The lock's directory is created with a plain, non-`-p` `mkdir` (an
atomic lock primitive), so its parent must pre-exist; that is the whole
reason for the preamble. Since the lock lives only on the primary host,
the run directory only needs pre-creating there.

Everything else under the run directory self-creates with `mkdir -p` on
the hosts where it runs: env files and secrets
(`app`/`accessory.ensure_env_directory`), proxy config, and the audit
log (`Auditor#record` prepends its own `mkdir -p`). None of them rely
on this preamble, so narrowing it to the primary host changes no other
behaviour.
Copilot AI review requested due to automatic review settings July 7, 2026 09:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reduces unnecessary SSH fan-out by limiting .kamal run directory creation (ensure_run_directory) to only the primary host, aligning the precondition with how the deploy lock is actually acquired and stored.

Changes:

  • Update ensure_run_directory to run only on KAMAL.primary_host instead of all configured hosts.
  • Add a CLI lock test asserting .kamal is created only on the primary host during kamal lock acquire.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
test/cli/lock_test.rb Adds coverage to ensure the run directory preamble only targets the primary host during lock acquire.
lib/kamal/cli/base.rb Narrows ensure_run_directory execution scope to the primary host to avoid unnecessary connections.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants