Configurable Kamal directory

To avoid polluting the default SSH directory with lots of Kamal config,
we'll default to putting them in a `kamal` sub directory.

But also make the directory configurable with the `run_directory` key,
so for example you can set it as `/var/run/kamal/`

The directory is created during bootstrap or before any command that
will need to access a file.
This commit is contained in:
Donal McBreen
2023-08-28 16:12:56 +01:00
parent 9363b6a464
commit bcfa1d83e8
17 changed files with 101 additions and 23 deletions

View File

@@ -20,7 +20,7 @@ class CliBuildTest < CliTestCase
end
test "push without builder" do
stub_locking
stub_setup
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
.with(:docker, "--version", "&&", :docker, :buildx, "version")
@@ -36,7 +36,7 @@ class CliBuildTest < CliTestCase
end
test "push with no buildx plugin" do
stub_locking
stub_setup
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
.with(:docker, "--version", "&&", :docker, :buildx, "version")
.raises(SSHKit::Command::Failed.new("no buildx"))
@@ -67,7 +67,7 @@ class CliBuildTest < CliTestCase
end
test "create with error" do
stub_locking
stub_setup
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
.with { |arg| arg == :docker }
.raises(SSHKit::Command::Failed.new("stderr=error"))

View File

@@ -27,11 +27,13 @@ class CliTestCase < ActiveSupport::TestCase
.raises(SSHKit::Command::Failed.new("failed"))
end
def stub_locking
def stub_setup
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
.with { |arg1, arg2| arg1 == :mkdir && arg2 == "kamal_lock-app" }
.with { |*args| args == [ :mkdir, "-p", "kamal" ] }
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
.with { |arg1, arg2| arg1 == :rm && arg2 == "kamal_lock-app/details" }
.with { |arg1, arg2| arg1 == :mkdir && arg2 == "kamal/lock-app" }
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
.with { |arg1, arg2| arg1 == :rm && arg2 == "kamal/lock-app/details" }
end
def assert_hook_ran(hook, output, version:, service_version:, hosts:, command:, subcommand: nil, runtime: nil)

View File

@@ -63,11 +63,14 @@ class CliMainTest < CliTestCase
Thread.report_on_exception = false
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
.with { |*arg| arg[0..1] == [:mkdir, 'kamal_lock-app'] }
.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")
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/lock-app', ">", "/dev/null", "&&", :cat, "kamal/lock-app/details", "|", :base64, "-d")
assert_raises(Kamal::Cli::LockError) do
run_command("deploy")
@@ -78,7 +81,10 @@ class CliMainTest < CliTestCase
Thread.report_on_exception = false
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
.with { |*arg| arg[0..1] == [:mkdir, 'kamal_lock-app'] }
.with { |*args| args == [ :mkdir, "-p", "kamal" ] }
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
.with { |*arg| arg[0..1] == [:mkdir, 'kamal/lock-app'] }
.raises(SocketError, "getaddrinfo: nodename nor servname provided, or not known")
assert_raises(SSHKit::Runner::ExecuteError) do
@@ -230,7 +236,7 @@ class CliMainTest < CliTestCase
test "audit" do
run_command("audit").tap do |output|
assert_match /tail -n 50 kamal-app-audit.log on 1.1.1.1/, output
assert_match %r{tail -n 50 kamal/app-audit.log on 1.1.1.1}, output
assert_match /App Host: 1.1.1.1/, output
end
end

View File

@@ -3,6 +3,7 @@ require_relative "cli_test_case"
class CliServerTest < CliTestCase
test "bootstrap already installed" do
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:docker, "-v", raise_on_non_zero_exit: false).returns(true).at_least_once
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:mkdir, "-p", "kamal").returns("").at_least_once
assert_equal "", run_command("bootstrap")
end
@@ -10,6 +11,7 @@ class CliServerTest < CliTestCase
test "bootstrap install as non-root user" do
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:docker, "-v", raise_on_non_zero_exit: false).returns(false).at_least_once
SSHKit::Backend::Abstract.any_instance.expects(:execute).with('[ "${EUID:-$(id -u)}" -eq 0 ]', raise_on_non_zero_exit: false).returns(false).at_least_once
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:mkdir, "-p", "kamal").returns("").at_least_once
assert_raise RuntimeError, "Docker is not installed on 1.1.1.1, 1.1.1.3, 1.1.1.4, 1.1.1.2 and can't be automatically installed without having root access and the `curl` command available. Install Docker manually: https://docs.docker.com/engine/install/" do
run_command("bootstrap")
@@ -20,6 +22,7 @@ class CliServerTest < CliTestCase
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:docker, "-v", raise_on_non_zero_exit: false).returns(false).at_least_once
SSHKit::Backend::Abstract.any_instance.expects(:execute).with('[ "${EUID:-$(id -u)}" -eq 0 ]', raise_on_non_zero_exit: false).returns(true).at_least_once
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:curl, "-fsSL", "https://get.docker.com", "|", :sh).at_least_once
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:mkdir, "-p", "kamal").returns("").at_least_once
run_command("bootstrap").tap do |output|
("1.1.1.1".."1.1.1.4").map do |host|

View File

@@ -20,7 +20,7 @@ class CliTraefikTest < CliTestCase
test "reboot --rolling" do
run_command("reboot", "--rolling").tap do |output|
assert_match "Running docker container prune --force --filter label=org.opencontainers.image.title=Traefik on 1.1.1.1", output.lines[3]
assert_match "Running docker container prune --force --filter label=org.opencontainers.image.title=Traefik on 1.1.1.1", output
end
end