Set env variables when running kamal app exec

Allow additional env variable to be set when running `kamal app exec`.
Works for both new and existing containers.
This commit is contained in:
Donal McBreen
2024-04-01 15:01:32 +01:00
parent 2562853ae3
commit 8a6a51977f
3 changed files with 32 additions and 16 deletions

View File

@@ -70,13 +70,15 @@ class Kamal::Cli::App < Kamal::Cli::Base
desc "exec [CMD]", "Execute a custom command on servers (use --help to show options)"
option :interactive, aliases: "-i", type: :boolean, default: false, desc: "Execute command over ssh for an interactive shell (use for console/bash)"
option :reuse, type: :boolean, default: false, desc: "Reuse currently running container instead of starting a new one"
option :env, aliases: "-e", type: :hash, desc: "Set environment variables for the command"
def exec(cmd)
env = options[:env]
case
when options[:interactive] && options[:reuse]
say "Get current version of running container...", :magenta unless options[:version]
using_version(options[:version] || current_running_version) do |version|
say "Launching interactive command with version #{version} via SSH from existing container on #{KAMAL.primary_host}...", :magenta
run_locally { exec KAMAL.app(role: KAMAL.primary_role).execute_in_existing_container_over_ssh(cmd, host: KAMAL.primary_host) }
run_locally { exec KAMAL.app(role: KAMAL.primary_role).execute_in_existing_container_over_ssh(cmd, host: KAMAL.primary_host, env: env) }
end
when options[:interactive]
@@ -84,7 +86,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
using_version(version_or_latest) do |version|
say "Launching interactive command with version #{version} via SSH from new container on #{KAMAL.primary_host}...", :magenta
run_locally do
exec KAMAL.app(role: KAMAL.primary_role).execute_in_new_container_over_ssh(cmd, host: KAMAL.primary_host)
exec KAMAL.app(role: KAMAL.primary_role).execute_in_new_container_over_ssh(cmd, host: KAMAL.primary_host, env: env)
end
end
@@ -98,7 +100,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
roles.each do |role|
execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on app version #{version}", role: role), verbosity: :debug
puts_by_host host, capture_with_info(*KAMAL.app(role: role).execute_in_existing_container(cmd))
puts_by_host host, capture_with_info(*KAMAL.app(role: role).execute_in_existing_container(cmd, env: env))
end
end
end
@@ -112,7 +114,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
roles.each do |role|
execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on app version #{version}"), verbosity: :debug
puts_by_host host, capture_with_info(*KAMAL.app(role: role).execute_in_new_container(cmd))
puts_by_host host, capture_with_info(*KAMAL.app(role: role).execute_in_new_container(cmd, env: env))
end
end
end

View File

@@ -1,27 +1,29 @@
module Kamal::Commands::App::Execution
def execute_in_existing_container(*command, interactive: false)
def execute_in_existing_container(*command, interactive: false, env:)
docker :exec,
("-it" if interactive),
*argumentize("--env", env),
container_name,
*command
end
def execute_in_new_container(*command, interactive: false)
def execute_in_new_container(*command, interactive: false, env:)
docker :run,
("-it" if interactive),
"--rm",
*role&.env_args,
*argumentize("--env", env),
*config.volume_args,
*role&.option_args,
config.absolute_image,
*command
end
def execute_in_existing_container_over_ssh(*command, host:)
run_over_ssh execute_in_existing_container(*command, interactive: true), host: host
def execute_in_existing_container_over_ssh(*command, host:, env:)
run_over_ssh execute_in_existing_container(*command, interactive: true, env: env), host: host
end
def execute_in_new_container_over_ssh(*command, host:)
run_over_ssh execute_in_new_container(*command, interactive: true), host: host
def execute_in_new_container_over_ssh(*command, host:, env:)
run_over_ssh execute_in_new_container(*command, interactive: true, env: env), host: host
end
end