From 3b72e6293ffd38feacaaf6a8dac193b5b8edf4cc Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Mon, 9 Dec 2024 12:43:39 +0000 Subject: [PATCH] Support sshkit.default_env Enables deploy to MacOS hosts. Will still need further configuration though: - `default_env` needs to be set to a PATH that contains docker and coreutils `cp` - desktop docker config needs to have no `credsStore` - shell needs to be changed to `bash` All this can be done by the user though, whereas passing on `default_env` to SSHKit needed to happen on Kamal. cc @dhh, @HLFH See https://github.com/basecamp/kamal/issues/432#issuecomment-2505075808 for details. --- lib/kamal/commander.rb | 1 + lib/kamal/configuration/docs/sshkit.yml | 7 +++++++ lib/kamal/configuration/sshkit.rb | 6 +++++- lib/kamal/configuration/validator/sshkit.rb | 9 +++++++++ test/configuration/sshkit_test.rb | 6 ++++++ 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 lib/kamal/configuration/validator/sshkit.rb diff --git a/lib/kamal/commander.rb b/lib/kamal/commander.rb index 1557df57b..d8d6af0a6 100644 --- a/lib/kamal/commander.rb +++ b/lib/kamal/commander.rb @@ -168,6 +168,7 @@ def configure_sshkit_with(config) end SSHKit.config.command_map[:docker] = "docker" # No need to use /usr/bin/env, just clogs up the logs SSHKit.config.output_verbosity = verbosity + SSHKit.config.default_env = config.sshkit.default_env end def specifics diff --git a/lib/kamal/configuration/docs/sshkit.yml b/lib/kamal/configuration/docs/sshkit.yml index 0051dc8da..1e7fdfdcb 100644 --- a/lib/kamal/configuration/docs/sshkit.yml +++ b/lib/kamal/configuration/docs/sshkit.yml @@ -21,3 +21,10 @@ sshkit: # Kamal sets a long idle timeout of 900 seconds on connections to try to avoid # re-connection storms after an idle period, such as building an image or waiting for CI. pool_idle_timeout: 300 + + # Default Env + # + # SSHKit sessions do not inherit the host PATH value. If you need to set custom env vars on + # a SSHKit session, like PATH or DOCKER_DEFAULT_PLATFORM you can map them here. + default_env: + path: /usr/local/bin:$PATH" \ No newline at end of file diff --git a/lib/kamal/configuration/sshkit.rb b/lib/kamal/configuration/sshkit.rb index 9d4d61ce3..38289015c 100644 --- a/lib/kamal/configuration/sshkit.rb +++ b/lib/kamal/configuration/sshkit.rb @@ -5,7 +5,7 @@ class Kamal::Configuration::Sshkit def initialize(config:) @sshkit_config = config.raw_config.sshkit || {} - validate! sshkit_config + validate! sshkit_config, with: Kamal::Configuration::Validator::Sshkit end def max_concurrent_starts @@ -16,6 +16,10 @@ def pool_idle_timeout sshkit_config.fetch("pool_idle_timeout", 900) end + def default_env + sshkit_config.fetch("default_env", {}).transform_keys(&:to_sym) + end + def to_h sshkit_config end diff --git a/lib/kamal/configuration/validator/sshkit.rb b/lib/kamal/configuration/validator/sshkit.rb new file mode 100644 index 000000000..71b11d4ad --- /dev/null +++ b/lib/kamal/configuration/validator/sshkit.rb @@ -0,0 +1,9 @@ +class Kamal::Configuration::Validator::Sshkit < Kamal::Configuration::Validator + def validate! + validate_against_example! \ + config.except("default_env"), + example.except("default_env") + + validate_hash_of!(config["default_env"], String) + end +end diff --git a/test/configuration/sshkit_test.rb b/test/configuration/sshkit_test.rb index 1608e6eee..80f9559c2 100644 --- a/test/configuration/sshkit_test.rb +++ b/test/configuration/sshkit_test.rb @@ -25,4 +25,10 @@ class ConfigurationSshkitTest < ActiveSupport::TestCase @config = Kamal::Configuration.new(@deploy.tap { |c| c.merge!(sshkit: { "pool_idle_timeout" => 600 }) }) assert_equal 600, @config.sshkit.pool_idle_timeout end + + test "sshkit default env" do + assert_equal {}, @config.sshkit.default_env + @config = Kamal::Configuration.new(@deploy.tap { |c| c.merge!(sshkit: { "default_env" => {"path" => "/usr/local/bin:$PATH" } }) }) + assert_equal {path: "/usr/local/bin:$PATH" }, @config.sshkit.default_env + end end