diff --git a/lib/kamal/cli/base.rb b/lib/kamal/cli/base.rb index 12a72e66..39b546f1 100644 --- a/lib/kamal/cli/base.rb +++ b/lib/kamal/cli/base.rb @@ -84,7 +84,7 @@ module Kamal::Cli run_hook "pre-connect" - ensure_run_directory + ensure_run_and_locks_directory acquire_lock @@ -186,10 +186,14 @@ module Kamal::Cli instance_variable_get("@_invocations").first end - def ensure_run_directory + def ensure_run_and_locks_directory on(KAMAL.hosts) do execute(*KAMAL.server.ensure_run_directory) end + + on(KAMAL.primary_host) do + execute(*KAMAL.lock.ensure_locks_directory) + end end end end diff --git a/lib/kamal/commands/lock.rb b/lib/kamal/commands/lock.rb index 9b535f5f..395b6f3a 100644 --- a/lib/kamal/commands/lock.rb +++ b/lib/kamal/commands/lock.rb @@ -21,6 +21,10 @@ class Kamal::Commands::Lock < Kamal::Commands::Base read_lock_details end + def ensure_locks_directory + [ :mkdir, "-p", locks_dir ] + end + private def write_lock_details(message, version) write \ @@ -40,12 +44,18 @@ class Kamal::Commands::Lock < Kamal::Commands::Base "/dev/null" end + def locks_dir + File.join(config.run_directory, "locks") + end + def lock_dir - "#{config.run_directory}/lock-#{config.service}" + dir_name = [ config.service, config.destination ].compact.join("-") + + File.join(locks_dir, dir_name) end def lock_details_file - [ lock_dir, :details ].join("/") + File.join(lock_dir, "details") end def lock_details(message, version) diff --git a/test/cli/app_test.rb b/test/cli/app_test.rb index 717531f2..416bd895 100644 --- a/test/cli/app_test.rb +++ b/test/cli/app_test.rb @@ -45,7 +45,7 @@ class CliAppTest < CliTestCase end test "boot uses group strategy when specified" do - Kamal::Cli::App.any_instance.stubs(:on).with("1.1.1.1").twice # acquire & release lock + Kamal::Cli::App.any_instance.stubs(:on).with("1.1.1.1").times(3) # ensure locks dir, acquire & release lock Kamal::Cli::App.any_instance.stubs(:on).with([ "1.1.1.1" ]) # tag container # Strategy is used when booting the containers diff --git a/test/cli/cli_test_case.rb b/test/cli/cli_test_case.rb index ebe92293..1e103715 100644 --- a/test/cli/cli_test_case.rb +++ b/test/cli/cli_test_case.rb @@ -31,9 +31,11 @@ class CliTestCase < ActiveSupport::TestCase SSHKit::Backend::Abstract.any_instance.stubs(:execute) .with { |*args| args == [ :mkdir, "-p", ".kamal" ] } SSHKit::Backend::Abstract.any_instance.stubs(:execute) - .with { |arg1, arg2| arg1 == :mkdir && arg2 == ".kamal/lock-app" } + .with { |arg1, arg2, arg3| arg1 == :mkdir && arg2 == "-p" && arg3 == ".kamal/locks" } SSHKit::Backend::Abstract.any_instance.stubs(:execute) - .with { |arg1, arg2| arg1 == :rm && arg2 == ".kamal/lock-app/details" } + .with { |arg1, arg2| arg1 == :mkdir && arg2 == ".kamal/locks/app" } + SSHKit::Backend::Abstract.any_instance.stubs(:execute) + .with { |arg1, arg2| arg1 == :rm && arg2 == ".kamal/locks/app/details" } end def assert_hook_ran(hook, output, version:, service_version:, hosts:, command:, subcommand: nil, runtime: nil) diff --git a/test/cli/lock_test.rb b/test/cli/lock_test.rb index 66482153..f6874d49 100644 --- a/test/cli/lock_test.rb +++ b/test/cli/lock_test.rb @@ -3,7 +3,7 @@ require_relative "cli_test_case" class CliLockTest < CliTestCase test "status" do run_command("status").tap do |output| - assert_match "Running /usr/bin/env stat .kamal/lock-app > /dev/null && cat .kamal/lock-app/details | base64 -d on 1.1.1.1", output + assert_match "Running /usr/bin/env stat .kamal/locks/app > /dev/null && cat .kamal/locks/app/details | base64 -d on 1.1.1.1", output end end diff --git a/test/cli/main_test.rb b/test/cli/main_test.rb index 2c0bd476..6111ade8 100644 --- a/test/cli/main_test.rb +++ b/test/cli/main_test.rb @@ -102,11 +102,14 @@ class CliMainTest < CliTestCase .with { |*args| args == [ :mkdir, "-p", ".kamal" ] } SSHKit::Backend::Abstract.any_instance.stubs(:execute) - .with { |*arg| arg[0..1] == [ :mkdir, ".kamal/lock-app" ] } - .raises(RuntimeError, "mkdir: cannot create directory ‘kamal_lock-app’: File exists") + .with { |*args| args == [ :mkdir, "-p", ".kamal/locks" ] } + + SSHKit::Backend::Abstract.any_instance.stubs(:execute) + .with { |*arg| arg[0..1] == [ :mkdir, ".kamal/locks/app" ] } + .raises(RuntimeError, "mkdir: cannot create directory ‘kamal/locks/app’: File exists") SSHKit::Backend::Abstract.any_instance.expects(:capture_with_debug) - .with(:stat, ".kamal/lock-app", ">", "/dev/null", "&&", :cat, ".kamal/lock-app/details", "|", :base64, "-d") + .with(:stat, ".kamal/locks/app", ">", "/dev/null", "&&", :cat, ".kamal/locks/app/details", "|", :base64, "-d") assert_raises(Kamal::Cli::LockError) do run_command("deploy") @@ -120,7 +123,10 @@ class CliMainTest < CliTestCase .with { |*args| args == [ :mkdir, "-p", ".kamal" ] } SSHKit::Backend::Abstract.any_instance.stubs(:execute) - .with { |*arg| arg[0..1] == [ :mkdir, ".kamal/lock-app" ] } + .with { |*args| args == [ :mkdir, "-p", ".kamal/locks" ] } + + SSHKit::Backend::Abstract.any_instance.stubs(:execute) + .with { |*arg| arg[0..1] == [ :mkdir, ".kamal/locks/app" ] } .raises(SocketError, "getaddrinfo: nodename nor servname provided, or not known") assert_raises(SSHKit::Runner::ExecuteError) do diff --git a/test/commands/lock_test.rb b/test/commands/lock_test.rb index dc8981f9..fc2b15ab 100644 --- a/test/commands/lock_test.rb +++ b/test/commands/lock_test.rb @@ -10,24 +10,24 @@ class CommandsLockTest < ActiveSupport::TestCase test "status" do assert_equal \ - "stat .kamal/lock-app > /dev/null && cat .kamal/lock-app/details | base64 -d", + "stat .kamal/locks/app-production > /dev/null && cat .kamal/locks/app-production/details | base64 -d", new_command.status.join(" ") end test "acquire" do assert_match \ - %r{mkdir \.kamal/lock-app && echo ".*" > \.kamal/lock-app/details}m, + %r{mkdir \.kamal/locks/app-production && echo ".*" > \.kamal/locks/app-production/details}m, new_command.acquire("Hello", "123").join(" ") end test "release" do assert_match \ - "rm .kamal/lock-app/details && rm -r .kamal/lock-app", + "rm .kamal/locks/app-production/details && rm -r .kamal/locks/app-production", new_command.release.join(" ") end private def new_command - Kamal::Commands::Lock.new(Kamal::Configuration.new(@config, version: "123")) + Kamal::Commands::Lock.new(Kamal::Configuration.new(@config, version: "123", destination: "production")) end end