Avoid setting env via SSHKit
SSHKit puts the env in the command, so leaks them in process listings.
This commit is contained in:
@@ -135,8 +135,10 @@ module Kamal::Cli
|
||||
details = { hosts: KAMAL.hosts.join(","), command: command, subcommand: subcommand }
|
||||
|
||||
say "Running the #{hook} hook...", :magenta
|
||||
with_env KAMAL.hook.env(**details, **extra_details) do
|
||||
run_locally do
|
||||
execute *KAMAL.hook.run(hook, **details, **extra_details)
|
||||
execute *KAMAL.hook.run(hook)
|
||||
end
|
||||
rescue SSHKit::Command::Failed => e
|
||||
raise HookError.new("Hook `#{hook}` failed:\n#{e.message}")
|
||||
end
|
||||
@@ -183,5 +185,14 @@ module Kamal::Cli
|
||||
execute(*KAMAL.server.ensure_run_directory)
|
||||
end
|
||||
end
|
||||
|
||||
def with_env(env)
|
||||
current_env = ENV.to_h.dup
|
||||
ENV.update(env)
|
||||
yield
|
||||
ensure
|
||||
ENV.clear
|
||||
ENV.update(current_env)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,6 +30,7 @@ class Kamal::Cli::Build < Kamal::Cli::Base
|
||||
say "Building with uncommitted changes:\n #{uncommitted_changes}", :yellow
|
||||
end
|
||||
|
||||
with_env(KAMAL.config.builder.secrets) do
|
||||
run_locally do
|
||||
begin
|
||||
execute *KAMAL.builder.inspect_builder
|
||||
@@ -51,7 +52,8 @@ class Kamal::Cli::Build < Kamal::Cli::Base
|
||||
push = KAMAL.builder.push
|
||||
|
||||
KAMAL.with_verbosity(:debug) do
|
||||
Dir.chdir(KAMAL.config.builder.build_directory) { execute *push, env: KAMAL.config.builder.secrets }
|
||||
Dir.chdir(KAMAL.config.builder.build_directory) { execute *push }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,7 +48,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
|
||||
end
|
||||
end
|
||||
|
||||
run_hook "post-deploy", secrets: true, runtime: runtime.round
|
||||
run_hook "post-deploy", secrets: true, runtime: runtime.round.to_s
|
||||
end
|
||||
|
||||
desc "redeploy", "Deploy app to servers without bootstrapping servers, starting kamal-proxy, pruning, and registry login"
|
||||
@@ -75,7 +75,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
|
||||
end
|
||||
end
|
||||
|
||||
run_hook "post-deploy", secrets: true, runtime: runtime.round
|
||||
run_hook "post-deploy", secrets: true, runtime: runtime.round.to_s
|
||||
end
|
||||
|
||||
desc "rollback [VERSION]", "Rollback app to VERSION"
|
||||
@@ -99,7 +99,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
|
||||
end
|
||||
end
|
||||
|
||||
run_hook "post-deploy", secrets: true, runtime: runtime.round if rolled_back
|
||||
run_hook "post-deploy", secrets: true, runtime: runtime.round.to_s if rolled_back
|
||||
end
|
||||
|
||||
desc "details", "Show details about all containers"
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
class Kamal::Commands::Hook < Kamal::Commands::Base
|
||||
def run(hook, secrets: false, **details)
|
||||
env = tags(**details).env
|
||||
env.merge!(config.secrets.to_h) if secrets
|
||||
def run(hook)
|
||||
[ hook_file(hook) ]
|
||||
end
|
||||
|
||||
[ hook_file(hook), env: env ]
|
||||
def env(secrets: false, **details)
|
||||
tags(**details).env.tap do |env|
|
||||
env.merge!(config.secrets.to_h) if secrets
|
||||
end
|
||||
end
|
||||
|
||||
def hook_exists?(hook)
|
||||
|
||||
@@ -49,7 +49,7 @@ class CliBuildTest < CliTestCase
|
||||
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:git, "-C", build_directory, :submodule, :update, "--init")
|
||||
|
||||
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
||||
.with(:docker, :buildx, :build, "--push", "--platform", "linux/amd64", "--builder", "kamal-local-docker-container", "-t", "dhh/app:999", "-t", "dhh/app:latest", "--label", "service=\"app\"", "--file", "Dockerfile", ".", env: {})
|
||||
.with(:docker, :buildx, :build, "--push", "--platform", "linux/amd64", "--builder", "kamal-local-docker-container", "-t", "dhh/app:999", "-t", "dhh/app:latest", "--label", "service=\"app\"", "--file", "Dockerfile", ".")
|
||||
|
||||
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
|
||||
.with(:git, "-C", anything, :"rev-parse", :HEAD)
|
||||
@@ -140,7 +140,7 @@ class CliBuildTest < CliTestCase
|
||||
.returns("")
|
||||
|
||||
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
||||
.with(:docker, :buildx, :build, "--push", "--platform", "linux/amd64", "--builder", "kamal-local-docker-container", "-t", "dhh/app:999", "-t", "dhh/app:latest", "--label", "service=\"app\"", "--file", "Dockerfile", ".", env: {})
|
||||
.with(:docker, :buildx, :build, "--push", "--platform", "linux/amd64", "--builder", "kamal-local-docker-container", "-t", "dhh/app:999", "-t", "dhh/app:latest", "--label", "service=\"app\"", "--file", "Dockerfile", ".")
|
||||
|
||||
run_command("push").tap do |output|
|
||||
assert_match /WARN Missing compatible builder, so creating a new one first/, output
|
||||
|
||||
@@ -41,27 +41,7 @@ class CliTestCase < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
def assert_hook_ran(hook, output, version:, service_version:, hosts:, command:, subcommand: nil, runtime: false, secrets: false)
|
||||
whoami = `whoami`.chomp
|
||||
performer = Kamal::Git.email.presence || whoami
|
||||
service = service_version.split("@").first
|
||||
|
||||
assert_match "Running the #{hook} hook...\n", output
|
||||
|
||||
expected = %r{Running\s/usr/bin/env\s\.kamal/hooks/#{hook}\sas\s#{whoami}@localhost\n\s
|
||||
DEBUG\s\[[0-9a-f]*\]\sCommand:\s\(\sexport\s
|
||||
KAMAL_RECORDED_AT=\"\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ\"\s
|
||||
KAMAL_PERFORMER=\"#{performer}\"\s
|
||||
KAMAL_VERSION=\"#{version}\"\s
|
||||
KAMAL_SERVICE_VERSION=\"#{service_version}\"\s
|
||||
KAMAL_SERVICE=\"#{service}\"\s
|
||||
KAMAL_HOSTS=\"#{hosts}\"\s
|
||||
KAMAL_COMMAND=\"#{command}\"\s
|
||||
#{"KAMAL_SUBCOMMAND=\\\"#{subcommand}\\\"\\s" if subcommand}
|
||||
#{"KAMAL_RUNTIME=\\\"\\d+\\\"\\s" if runtime}
|
||||
#{"DB_PASSWORD=\"secret\"\\s" if secrets}
|
||||
;\s/usr/bin/env\s\.kamal/hooks/#{hook} }x
|
||||
|
||||
assert_match expected, output
|
||||
assert_match %r{usr/bin/env\s\.kamal/hooks/#{hook}}, output
|
||||
end
|
||||
|
||||
def with_argv(*argv)
|
||||
|
||||
@@ -16,41 +16,34 @@ class CommandsHookTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "run" do
|
||||
assert_equal [
|
||||
".kamal/hooks/foo",
|
||||
{ env: {
|
||||
assert_equal [ ".kamal/hooks/foo" ], new_command.run("foo")
|
||||
end
|
||||
|
||||
test "env" do
|
||||
assert_equal ({
|
||||
"KAMAL_RECORDED_AT" => @recorded_at,
|
||||
"KAMAL_PERFORMER" => @performer,
|
||||
"KAMAL_VERSION" => "123",
|
||||
"KAMAL_SERVICE_VERSION" => "app@123",
|
||||
"KAMAL_SERVICE" => "app" } }
|
||||
], new_command.run("foo")
|
||||
"KAMAL_SERVICE" => "app"
|
||||
}), new_command.env
|
||||
end
|
||||
|
||||
test "run with custom hooks_path" do
|
||||
assert_equal [
|
||||
"custom/hooks/path/foo",
|
||||
{ env: {
|
||||
"KAMAL_RECORDED_AT" => @recorded_at,
|
||||
"KAMAL_PERFORMER" => @performer,
|
||||
"KAMAL_VERSION" => "123",
|
||||
"KAMAL_SERVICE_VERSION" => "app@123",
|
||||
"KAMAL_SERVICE" => "app" } }
|
||||
], new_command(hooks_path: "custom/hooks/path").run("foo")
|
||||
assert_equal [ "custom/hooks/path/foo" ], new_command(hooks_path: "custom/hooks/path").run("foo")
|
||||
end
|
||||
|
||||
test "hook with secrets" do
|
||||
test "env with secrets" do
|
||||
with_test_secrets("secrets" => "DB_PASSWORD=secret") do
|
||||
assert_equal [
|
||||
".kamal/hooks/foo",
|
||||
{ env: {
|
||||
assert_equal (
|
||||
{
|
||||
"KAMAL_RECORDED_AT" => @recorded_at,
|
||||
"KAMAL_PERFORMER" => @performer,
|
||||
"KAMAL_VERSION" => "123",
|
||||
"KAMAL_SERVICE_VERSION" => "app@123",
|
||||
"KAMAL_SERVICE" => "app",
|
||||
"DB_PASSWORD" => "secret" } }
|
||||
], new_command(env: { "secret" => [ "DB_PASSWORD" ] }).run("foo", secrets: true)
|
||||
"DB_PASSWORD" => "secret" }
|
||||
), new_command.env(secrets: true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user