Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/kamal/commands/app/execution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def execute_in_new_container(*command, interactive: false, detach: false, env:)
(docker_interactive_args if interactive),
("--detach" if detach),
("--rm" unless detach),
"--name", container_name_for_exec,
"--network", "kamal",
*role&.env_args(host),
*argumentize("--env", env),
Expand All @@ -22,11 +23,16 @@ def execute_in_new_container(*command, interactive: false, detach: false, env:)
*command
end

def execute_in_existing_container_over_ssh(*command, env:)
def execute_in_existing_container_over_ssh(*command, env:)
run_over_ssh execute_in_existing_container(*command, interactive: true, env: env), host: host
end

def execute_in_new_container_over_ssh(*command, env:)
run_over_ssh execute_in_new_container(*command, interactive: true, env: env), host: host
end

private
def container_name_for_exec
[ role.container_prefix, "exec", config.version, SecureRandom.hex(3) ].compact.join("-")
end
end
8 changes: 4 additions & 4 deletions test/cli/app_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ class CliAppTest < CliTestCase
test "exec" do
run_command("exec", "ruby -v").tap do |output|
assert_match "docker login -u [REDACTED] -p [REDACTED]", output
assert_match "docker run --rm --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" dhh/app:latest ruby -v", output
assert_match %r{docker run --rm --name app-web-exec-latest-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:latest ruby -v}, output
end
end

Expand All @@ -336,13 +336,13 @@ class CliAppTest < CliTestCase

test "exec separate arguments" do
run_command("exec", "ruby", " -v").tap do |output|
assert_match "docker run --rm --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" dhh/app:latest ruby -v", output
assert_match %r{docker run --rm --name app-web-exec-latest-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:latest ruby -v}, output
end
end

test "exec detach" do
run_command("exec", "--detach", "ruby -v").tap do |output|
assert_match "docker run --detach --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" dhh/app:latest ruby -v", output
assert_match %r{docker run --detach --name app-web-exec-latest-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:latest ruby -v}, output
end
end

Expand Down Expand Up @@ -374,7 +374,7 @@ class CliAppTest < CliTestCase
test "exec interactive" do
Kamal::Commands::Hook.any_instance.stubs(:hook_exists?).returns(true)
SSHKit::Backend::Abstract.any_instance.expects(:exec)
.with("ssh -t root@1.1.1.1 -p 22 'docker run -it --rm --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" dhh/app:latest ruby -v'")
.with(regexp_matches(%r{ssh -t root@1\.1\.1\.1 -p 22 'docker run -it --rm --name app-web-exec-latest-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:latest ruby -v'}))

stub_stdin_tty do
run_command("exec", "-i", "ruby -v").tap do |output|
Expand Down
30 changes: 15 additions & 15 deletions test/commands/app_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -238,44 +238,44 @@ class CommandsAppTest < ActiveSupport::TestCase


test "execute in new container" do
assert_equal \
"docker run --rm --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" dhh/app:999 bin/rails db:setup",
assert_match \
%r{docker run --rm --name app-web-exec-999-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:999 bin/rails db:setup},
new_command.execute_in_new_container("bin/rails", "db:setup", env: {}).join(" ")
end

test "execute in new container with logging" do
@config[:logging] = { "driver" => "local", "options" => { "max-size" => "100m", "max-file" => "3" } }

assert_equal \
"docker run --rm --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-driver \"local\" --log-opt max-size=\"100m\" --log-opt max-file=\"3\" dhh/app:999 bin/rails db:setup",
assert_match \
%r{docker run --rm --name app-web-exec-999-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-driver "local" --log-opt max-size="100m" --log-opt max-file="3" dhh/app:999 bin/rails db:setup},
new_command.execute_in_new_container("bin/rails", "db:setup", env: {}).join(" ")
end

test "execute in new container with env" do
assert_equal \
"docker run --rm --network kamal --env-file .kamal/apps/app/env/roles/web.env --env foo=\"bar\" --log-opt max-size=\"10m\" dhh/app:999 bin/rails db:setup",
assert_match \
%r{docker run --rm --name app-web-exec-999-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --env foo="bar" --log-opt max-size="10m" dhh/app:999 bin/rails db:setup},
new_command.execute_in_new_container("bin/rails", "db:setup", env: { "foo" => "bar" }).join(" ")
end

test "execute in new detached container" do
assert_equal \
"docker run --detach --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" dhh/app:999 bin/rails db:setup",
assert_match \
%r{docker run --detach --name app-web-exec-999-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:999 bin/rails db:setup},
new_command.execute_in_new_container("bin/rails", "db:setup", detach: true, env: {}).join(" ")
end

test "execute in new container with tags" do
@config[:servers] = [ { "1.1.1.1" => "tag1" } ]
@config[:env]["tags"] = { "tag1" => { "ENV1" => "value1" } }

assert_equal \
"docker run --rm --network kamal --env ENV1=\"value1\" --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" dhh/app:999 bin/rails db:setup",
assert_match \
%r{docker run --rm --name app-web-exec-999-[0-9a-f]{6} --network kamal --env ENV1="value1" --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:999 bin/rails db:setup},
new_command.execute_in_new_container("bin/rails", "db:setup", env: {}).join(" ")
end

test "execute in new container with custom options" do
@config[:servers] = { "web" => { "hosts" => [ "1.1.1.1" ], "options" => { "mount" => "somewhere", "cap-add" => true } } }
assert_equal \
"docker run --rm --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" --mount \"somewhere\" --cap-add dhh/app:999 bin/rails db:setup",
assert_match \
%r{docker run --rm --name app-web-exec-999-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" --mount "somewhere" --cap-add dhh/app:999 bin/rails db:setup},
new_command.execute_in_new_container("bin/rails", "db:setup", env: {}).join(" ")
end

Expand All @@ -292,21 +292,21 @@ class CommandsAppTest < ActiveSupport::TestCase
end

test "execute in new container over ssh" do
assert_match %r{docker run -it --rm --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:999 bin/rails c},
assert_match %r{docker run -it --rm --name app-web-exec-999-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:999 bin/rails c},
stub_stdin_tty { new_command.execute_in_new_container_over_ssh("bin/rails", "c", env: {}) }
end

test "execute in new container over ssh with tags" do
@config[:servers] = [ { "1.1.1.1" => "tag1" } ]
@config[:env]["tags"] = { "tag1" => { "ENV1" => "value1" } }

assert_equal "ssh -t [email protected] -p 22 'docker run -it --rm --network kamal --env ENV1=\"value1\" --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" dhh/app:999 bin/rails c'",
assert_match %r{ssh -t [email protected] -p 22 'docker run -it --rm --name app-web-exec-999-[0-9a-f]{6} --network kamal --env ENV1="value1" --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size="10m" dhh/app:999 bin/rails c'},
stub_stdin_tty { new_command.execute_in_new_container_over_ssh("bin/rails", "c", env: {}) }
end

test "execute in new container with custom options over ssh" do
@config[:servers] = { "web" => { "hosts" => [ "1.1.1.1" ], "options" => { "mount" => "somewhere", "cap-add" => true } } }
assert_match %r{docker run -it --rm --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" --mount \"somewhere\" --cap-add dhh/app:999 bin/rails c},
assert_match %r{docker run -it --rm --name app-web-exec-999-[0-9a-f]{6} --network kamal --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" --mount \"somewhere\" --cap-add dhh/app:999 bin/rails c},
stub_stdin_tty { new_command.execute_in_new_container_over_ssh("bin/rails", "c", env: {}) }
end

Expand Down
Loading