From 13328687d122a3dd28fb5f9aec5a5e82b6a26335 Mon Sep 17 00:00:00 2001 From: Kohki Makimoto Date: Wed, 25 Sep 2024 21:35:39 +0900 Subject: [PATCH 01/26] support the "provenance" option in the "builder" config --- lib/kamal/commands/builder/base.rb | 8 ++++++-- lib/kamal/configuration/builder.rb | 4 ++++ lib/kamal/configuration/docs/builder.yml | 6 ++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/kamal/commands/builder/base.rb b/lib/kamal/commands/builder/base.rb index 636fe4f4..d551520b 100644 --- a/lib/kamal/commands/builder/base.rb +++ b/lib/kamal/commands/builder/base.rb @@ -6,7 +6,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base delegate :argumentize, to: Kamal::Utils delegate \ :args, :secrets, :dockerfile, :target, :arches, :local_arches, :remote_arches, :remote, - :cache_from, :cache_to, :ssh, :driver, :docker_driver?, + :cache_from, :cache_to, :ssh, :provenance, :driver, :docker_driver?, to: :builder_config def clean @@ -37,7 +37,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base end def build_options - [ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh ] + [ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh, *builder_provenance ] end def build_context @@ -97,6 +97,10 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base argumentize "--ssh", ssh if ssh.present? end + def builder_provenance + argumentize "--provenance", provenance unless provenance.nil? + end + def builder_config config.builder end diff --git a/lib/kamal/configuration/builder.rb b/lib/kamal/configuration/builder.rb index a395e228..d2f244db 100644 --- a/lib/kamal/configuration/builder.rb +++ b/lib/kamal/configuration/builder.rb @@ -111,6 +111,10 @@ class Kamal::Configuration::Builder builder_config["ssh"] end + def provenance + builder_config["provenance"] + end + def git_clone? Kamal::Git.used? && builder_config["context"].nil? end diff --git a/lib/kamal/configuration/docs/builder.yml b/lib/kamal/configuration/docs/builder.yml index cdde194f..2aefd006 100644 --- a/lib/kamal/configuration/docs/builder.yml +++ b/lib/kamal/configuration/docs/builder.yml @@ -104,3 +104,9 @@ builder: # # The build driver to use, defaults to `docker-container` driver: docker + + # Provenance + # + # It is used to configure provenance attestations for the build result. + # The value can also be a boolean to enable or disable provenance attestations. + provenance: mode=max From c17bdba61ca1d32a8603e6d9cc1f736c848fc2ed Mon Sep 17 00:00:00 2001 From: Kohki Makimoto Date: Wed, 25 Sep 2024 23:24:37 +0900 Subject: [PATCH 02/26] add tests --- test/commands/builder_test.rb | 7 +++++++ test/configuration/builder_test.rb | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/test/commands/builder_test.rb b/test/commands/builder_test.rb index e5daddfd..4e5e8046 100644 --- a/test/commands/builder_test.rb +++ b/test/commands/builder_test.rb @@ -144,6 +144,13 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder.push.join(" ") end + test "push with provenance" do + builder = new_builder_command(builder: { "provenance" => "mode=max" }) + assert_equal \ + "docker buildx build --push --platform linux/amd64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile --provenance mode=max .", + builder.push.join(" ") + end + test "mirror count" do command = new_builder_command assert_equal "docker info --format '{{index .RegistryConfig.Mirrors 0}}'", command.first_mirror.join(" ") diff --git a/test/configuration/builder_test.rb b/test/configuration/builder_test.rb index 53740ca8..545273b6 100644 --- a/test/configuration/builder_test.rb +++ b/test/configuration/builder_test.rb @@ -134,6 +134,16 @@ class ConfigurationBuilderTest < ActiveSupport::TestCase assert_equal "default=$SSH_AUTH_SOCK", config.builder.ssh end + test "provenance" do + assert_nil config.builder.provenance + end + + test "setting provenance" do + @deploy[:builder]["provenance"] = "mode=max" + + assert_equal "mode=max", config.builder.provenance + end + test "local disabled but no remote set" do @deploy[:builder]["local"] = false From 92d82dd1a78061b8992ea949ca81c722ef959aef Mon Sep 17 00:00:00 2001 From: Kohki Makimoto Date: Thu, 26 Sep 2024 05:50:51 +0900 Subject: [PATCH 03/26] test: If the provenance is false, output "--provenance false". --- test/commands/builder_test.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/commands/builder_test.rb b/test/commands/builder_test.rb index 4e5e8046..be75d6fa 100644 --- a/test/commands/builder_test.rb +++ b/test/commands/builder_test.rb @@ -151,6 +151,13 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder.push.join(" ") end + test "push with provenance false" do + builder = new_builder_command(builder: { "provenance" => false }) + assert_equal \ + "docker buildx build --push --platform linux/amd64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile --provenance false .", + builder.push.join(" ") + end + test "mirror count" do command = new_builder_command assert_equal "docker info --format '{{index .RegistryConfig.Mirrors 0}}'", command.first_mirror.join(" ") From 256933f6f31d630367374ac5dd75b0201f5419ac Mon Sep 17 00:00:00 2001 From: Adam Tanner Date: Wed, 18 Sep 2024 14:18:56 -0400 Subject: [PATCH 04/26] builder/cache/options: fix order of build args when using registry --- lib/kamal/configuration/builder.rb | 2 +- test/configuration/builder_test.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/kamal/configuration/builder.rb b/lib/kamal/configuration/builder.rb index a395e228..b4a01e9b 100644 --- a/lib/kamal/configuration/builder.rb +++ b/lib/kamal/configuration/builder.rb @@ -166,7 +166,7 @@ class Kamal::Configuration::Builder end def cache_to_config_for_registry - [ "type=registry", builder_config["cache"]&.fetch("options", nil), "ref=#{cache_image_ref}" ].compact.join(",") + [ "type=registry", "ref=#{cache_image_ref}", builder_config["cache"]&.fetch("options", nil) ].compact.join(",") end def repo_basename diff --git a/test/configuration/builder_test.rb b/test/configuration/builder_test.rb index 53740ca8..12580c56 100644 --- a/test/configuration/builder_test.rb +++ b/test/configuration/builder_test.rb @@ -64,7 +64,7 @@ class ConfigurationBuilderTest < ActiveSupport::TestCase @deploy[:builder] = { "arch" => "amd64", "cache" => { "type" => "registry", "options" => "mode=max,image-manifest=true,oci-mediatypes=true" } } assert_equal "type=registry,ref=dhh/app-build-cache", config.builder.cache_from - assert_equal "type=registry,mode=max,image-manifest=true,oci-mediatypes=true,ref=dhh/app-build-cache", config.builder.cache_to + assert_equal "type=registry,ref=dhh/app-build-cache,mode=max,image-manifest=true,oci-mediatypes=true", config.builder.cache_to end test "setting registry cache when using a custom registry" do @@ -72,14 +72,14 @@ class ConfigurationBuilderTest < ActiveSupport::TestCase @deploy[:builder] = { "arch" => "amd64", "cache" => { "type" => "registry", "options" => "mode=max,image-manifest=true,oci-mediatypes=true" } } assert_equal "type=registry,ref=registry.example.com/dhh/app-build-cache", config.builder.cache_from - assert_equal "type=registry,mode=max,image-manifest=true,oci-mediatypes=true,ref=registry.example.com/dhh/app-build-cache", config.builder.cache_to + assert_equal "type=registry,ref=registry.example.com/dhh/app-build-cache,mode=max,image-manifest=true,oci-mediatypes=true", config.builder.cache_to end test "setting registry cache with image" do @deploy[:builder] = { "arch" => "amd64", "cache" => { "type" => "registry", "image" => "kamal", "options" => "mode=max" } } assert_equal "type=registry,ref=kamal", config.builder.cache_from - assert_equal "type=registry,mode=max,ref=kamal", config.builder.cache_to + assert_equal "type=registry,ref=kamal,mode=max", config.builder.cache_to end test "args" do From ccf32c2c1f6068058a51a84fd8aa93dfc4b720bf Mon Sep 17 00:00:00 2001 From: junket Date: Thu, 3 Oct 2024 09:31:30 -0400 Subject: [PATCH 05/26] Pass false values in env vars to docker --- lib/kamal/utils.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/kamal/utils.rb b/lib/kamal/utils.rb index ab8dd50e..58daaa91 100644 --- a/lib/kamal/utils.rb +++ b/lib/kamal/utils.rb @@ -12,6 +12,8 @@ module Kamal::Utils attr = "#{key}=#{escape_shell_value(value)}" attr = self.sensitive(attr, redaction: "#{key}=[REDACTED]") if sensitive [ argument, attr ] + elsif value == false + [ argument, "#{key}=false" ] else [ argument, key ] end From 6d1d7a4c82be128beeff825834a849fa900b0b76 Mon Sep 17 00:00:00 2001 From: junket <789854+junket@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:05:54 -0400 Subject: [PATCH 06/26] Updates argumentize test for false values --- test/utils_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/utils_test.rb b/test/utils_test.rb index e292e980..a8fa0797 100644 --- a/test/utils_test.rb +++ b/test/utils_test.rb @@ -2,8 +2,8 @@ require "test_helper" class UtilsTest < ActiveSupport::TestCase test "argumentize" do - assert_equal [ "--label", "foo=\"\\`bar\\`\"", "--label", "baz=\"qux\"", "--label", :quux ], \ - Kamal::Utils.argumentize("--label", { foo: "`bar`", baz: "qux", quux: nil }) + assert_equal [ "--label", "foo=\"\\`bar\\`\"", "--label", "baz=\"qux\"", "--label", :quux, "--label", "quuz=false" ], \ + Kamal::Utils.argumentize("--label", { foo: "`bar`", baz: "qux", quux: nil, quuz: false }) end test "argumentize with redacted" do From f04cae529abfdf5b4a1930b804eced4a84db34ed Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Wed, 9 Oct 2024 09:53:17 +0400 Subject: [PATCH 07/26] Added network configuration option to application, proxy and accessory sections --- lib/kamal/commands/accessory.rb | 6 +++--- lib/kamal/commands/app.rb | 2 +- lib/kamal/commands/app/execution.rb | 2 +- lib/kamal/configuration.rb | 9 +++++++++ lib/kamal/configuration/accessory.rb | 10 ++++++++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/kamal/commands/accessory.rb b/lib/kamal/commands/accessory.rb index 0c1b9009..9abb6dfc 100644 --- a/lib/kamal/commands/accessory.rb +++ b/lib/kamal/commands/accessory.rb @@ -1,7 +1,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base attr_reader :accessory_config delegate :service_name, :image, :hosts, :port, :files, :directories, :cmd, - :publish_args, :env_args, :volume_args, :label_args, :option_args, + :network_args, :publish_args, :env_args, :volume_args, :label_args, :option_args, :secrets_io, :secrets_path, :env_directory, to: :accessory_config @@ -15,7 +15,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base "--name", service_name, "--detach", "--restart", "unless-stopped", - "--network", "kamal", + *network_args, *config.logging_args, *publish_args, *env_args, @@ -64,7 +64,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base docker :run, ("-it" if interactive), "--rm", - "--network", "kamal", + *network_args, *env_args, *volume_args, image, diff --git a/lib/kamal/commands/app.rb b/lib/kamal/commands/app.rb index 6d8f44c6..56a5656b 100644 --- a/lib/kamal/commands/app.rb +++ b/lib/kamal/commands/app.rb @@ -18,7 +18,7 @@ class Kamal::Commands::App < Kamal::Commands::Base "--detach", "--restart unless-stopped", "--name", container_name, - "--network", "kamal", + *config.network_args, *([ "--hostname", hostname ] if hostname), "-e", "KAMAL_CONTAINER_NAME=\"#{container_name}\"", "-e", "KAMAL_VERSION=\"#{config.version}\"", diff --git a/lib/kamal/commands/app/execution.rb b/lib/kamal/commands/app/execution.rb index 4434c26a..5770f7aa 100644 --- a/lib/kamal/commands/app/execution.rb +++ b/lib/kamal/commands/app/execution.rb @@ -11,7 +11,7 @@ module Kamal::Commands::App::Execution docker :run, ("-it" if interactive), "--rm", - "--network", "kamal", + *config.network_args, *role&.env_args(host), *argumentize("--env", env), *config.volume_args, diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index 09f1ed89..b26c30c9 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -18,6 +18,7 @@ class Kamal::Configuration PROXY_HTTP_PORT = 80 PROXY_HTTPS_PORT = 443 PROXY_LOG_MAX_SIZE = "10m" + NETWORK = "kamal" class << self def create_from(config_file:, destination: nil, version: nil) @@ -193,6 +194,10 @@ class Kamal::Configuration logging.args end + def network_args + argumentize "--network", network + end + def readiness_delay raw_config.readiness_delay || 7 @@ -297,6 +302,10 @@ class Kamal::Configuration end private + def network + raw_config["network"] || NETWORK + end + # Will raise ArgumentError if any required config keys are missing def ensure_destination_if_required if require_destination? && destination.nil? diff --git a/lib/kamal/configuration/accessory.rb b/lib/kamal/configuration/accessory.rb index 804a1502..7aed80ea 100644 --- a/lib/kamal/configuration/accessory.rb +++ b/lib/kamal/configuration/accessory.rb @@ -1,6 +1,8 @@ class Kamal::Configuration::Accessory include Kamal::Configuration::Validation + NETWORK = "kamal" + delegate :argumentize, :optionize, to: Kamal::Utils attr_reader :name, :accessory_config, :env @@ -38,6 +40,10 @@ class Kamal::Configuration::Accessory end end + def network_args + argumentize "--network", network + end + def publish_args argumentize "--publish", port if port end @@ -173,4 +179,8 @@ class Kamal::Configuration::Accessory accessory_config["roles"].flat_map { |role| config.role(role).hosts } end end + + def network + accessory_config["network"] || NETWORK + end end From c917dd82cf93c123c2e6afe78651bfe5df9bfd08 Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Tue, 1 Oct 2024 14:40:34 +0400 Subject: [PATCH 08/26] Added network_args to proxy configuration --- lib/kamal/commands/proxy.rb | 2 +- lib/kamal/configuration/proxy.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/kamal/commands/proxy.rb b/lib/kamal/commands/proxy.rb index acff3dbd..3399531f 100644 --- a/lib/kamal/commands/proxy.rb +++ b/lib/kamal/commands/proxy.rb @@ -4,7 +4,7 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base def run docker :run, "--name", container_name, - "--network", "kamal", + *config.network_args, "--detach", "--restart", "unless-stopped", "--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", diff --git a/lib/kamal/configuration/proxy.rb b/lib/kamal/configuration/proxy.rb index 6232c3e0..99c7aa1f 100644 --- a/lib/kamal/configuration/proxy.rb +++ b/lib/kamal/configuration/proxy.rb @@ -3,6 +3,7 @@ class Kamal::Configuration::Proxy DEFAULT_LOG_REQUEST_HEADERS = [ "Cache-Control", "Last-Modified", "User-Agent" ] CONTAINER_NAME = "kamal-proxy" + NETWORK = "kamal" delegate :argumentize, :optionize, to: Kamal::Utils @@ -51,6 +52,10 @@ class Kamal::Configuration::Proxy optionize ({ target: "#{target}:#{app_port}" }).merge(deploy_options), with: "=" end + def network_args + argumentize "--network", network + end + def merge(other) self.class.new config: config, proxy_config: proxy_config.deep_merge(other.proxy_config) end @@ -59,4 +64,8 @@ class Kamal::Configuration::Proxy def seconds_duration(value) value ? "#{value}s" : nil end + + def network + proxy_config["network"] || NETWORK + end end From b6a10df56aaff503edf5acb9389138ea39f60efe Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Tue, 1 Oct 2024 20:24:28 +0400 Subject: [PATCH 09/26] Added tests for network configuration option --- lib/kamal/configuration/docs/accessory.yml | 8 ++++++++ lib/kamal/configuration/docs/configuration.yml | 7 +++++++ lib/kamal/configuration/docs/proxy.yml | 7 +++++++ test/configuration/accessory_test.rb | 9 +++++++++ test/configuration/proxy_test.rb | 9 +++++++++ test/configuration_test.rb | 9 +++++++++ 6 files changed, 49 insertions(+) diff --git a/lib/kamal/configuration/docs/accessory.yml b/lib/kamal/configuration/docs/accessory.yml index 86d49b77..e77bf754 100644 --- a/lib/kamal/configuration/docs/accessory.yml +++ b/lib/kamal/configuration/docs/accessory.yml @@ -90,3 +90,11 @@ accessories: # They are not created or copied before mounting: volumes: - /path/to/mysql-logs:/var/log/mysql + + # Network + # + # The network the accessory will be attached to. + # + # Defaults to kamal: + network: custom + diff --git a/lib/kamal/configuration/docs/configuration.yml b/lib/kamal/configuration/docs/configuration.yml index 6b059346..b59394a3 100644 --- a/lib/kamal/configuration/docs/configuration.yml +++ b/lib/kamal/configuration/docs/configuration.yml @@ -176,3 +176,10 @@ logging: # Alias configuration, see kamal docs alias: aliases: ... + +# Network +# +# The network the application will be attached to. +# +# Defaults to kamal: +network: custom diff --git a/lib/kamal/configuration/docs/proxy.yml b/lib/kamal/configuration/docs/proxy.yml index 76ec3e41..0af14826 100644 --- a/lib/kamal/configuration/docs/proxy.yml +++ b/lib/kamal/configuration/docs/proxy.yml @@ -103,3 +103,10 @@ proxy: # By default, kamal-proxy will not forward the headers if the `ssl` option is set to `true`, and # will forward them if it is set to `false`. forward_headers: true + + # Network + # + # The network the proxy container will be attached to. + # + # Defaults to kamal: + network: custom diff --git a/test/configuration/accessory_test.rb b/test/configuration/accessory_test.rb index 2615dab6..f5220902 100644 --- a/test/configuration/accessory_test.rb +++ b/test/configuration/accessory_test.rb @@ -152,4 +152,13 @@ class ConfigurationAccessoryTest < ActiveSupport::TestCase test "options" do assert_equal [ "--cpus", "\"4\"", "--memory", "\"2GB\"" ], @config.accessory(:redis).option_args end + + test "network_args default" do + assert_equal [ "--network", "kamal" ], @config.accessory(:mysql).network_args + end + + test "network_args with configured options" do + @deploy[:accessories]["mysql"]["network"] = "database" + assert_equal [ "--network", "database" ], @config.accessory(:mysql).network_args + end end diff --git a/test/configuration/proxy_test.rb b/test/configuration/proxy_test.rb index 588e5a35..562c229f 100644 --- a/test/configuration/proxy_test.rb +++ b/test/configuration/proxy_test.rb @@ -38,6 +38,15 @@ class ConfigurationProxyTest < ActiveSupport::TestCase assert_not config.proxy.ssl? end + test "network_args defaults" do + assert_equal [ "--network", "kamal" ], config.proxy.network_args + end + + test "network_args with configured options" do + @deploy[:proxy] = { "network" => "example" } + assert_equal [ "--network", "example" ], config.proxy.network_args + end + private def config Kamal::Configuration.new(@deploy) diff --git a/test/configuration_test.rb b/test/configuration_test.rb index c1aaa697..da53ddb6 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -217,6 +217,15 @@ class ConfigurationTest < ActiveSupport::TestCase assert_equal [ "--log-driver", "\"local\"", "--log-opt", "max-size=\"100m\"", "--log-opt", "max-file=\"5\"" ], config.logging_args end + test "network_args default" do + assert_equal [ "--network", "kamal" ], @config.network_args + end + + test "network_args with configured options" do + config = Kamal::Configuration.new(@deploy.tap { |c| c.merge!(network: "custom") }) + assert_equal [ "--network", "custom" ], config.network_args + end + test "erb evaluation of yml config" do config = Kamal::Configuration.create_from config_file: Pathname.new(File.expand_path("fixtures/deploy.erb.yml", __dir__)) assert_equal "my-user", config.registry.username From 08dacd27458368c7228a5ba99945690d4c37233b Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Tue, 1 Oct 2024 20:41:36 +0400 Subject: [PATCH 10/26] Added command tests --- test/commands/accessory_test.rb | 8 ++++++++ test/commands/app_test.rb | 8 ++++++++ test/commands/proxy_test.rb | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/test/commands/accessory_test.rb b/test/commands/accessory_test.rb index f3d71ffd..1befd9e6 100644 --- a/test/commands/accessory_test.rb +++ b/test/commands/accessory_test.rb @@ -71,6 +71,14 @@ class CommandsAccessoryTest < ActiveSupport::TestCase new_command(:busybox).run.join(" ") end + test "run in custom network" do + @config[:accessories]["mysql"]["network"] = "custom" + + assert_equal \ + "docker run --name app-mysql --detach --restart unless-stopped --network custom --log-opt max-size=\"10m\" --publish 3306:3306 --env MYSQL_ROOT_HOST=\"%\" --env-file .kamal/apps/app/env/accessories/mysql.env --label service=\"app-mysql\" private.registry/mysql:8.0", + new_command(:mysql).run.join(" ") + end + test "start" do assert_equal \ "docker container start app-mysql", diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index 0e5cad79..403e90d4 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -64,6 +64,14 @@ class CommandsAppTest < ActiveSupport::TestCase new_command.run.join(" ") end + test "run in custom network" do + @config[:network] = "custom" + + assert_equal \ + "docker run --detach --restart unless-stopped --name app-web-999 --network custom -e KAMAL_CONTAINER_NAME=\"app-web-999\" -e KAMAL_VERSION=\"999\" --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" --label service=\"app\" --label role=\"web\" --label destination dhh/app:999", + new_command.run.join(" ") + end + test "start" do assert_equal \ "docker start app-web-999", diff --git a/test/commands/proxy_test.rb b/test/commands/proxy_test.rb index b7cc9f3d..80f420d2 100644 --- a/test/commands/proxy_test.rb +++ b/test/commands/proxy_test.rb @@ -27,6 +27,14 @@ class CommandsProxyTest < ActiveSupport::TestCase new_command.run.join(" ") end + test "run in custom network" do + @config[:network] = "custom" + + assert_equal \ + "docker run --name kamal-proxy --network custom --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy $(cat .kamal/proxy/options || echo \"--publish 80:80 --publish 443:443\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION}", + new_command.run.join(" ") + end + test "proxy start" do assert_equal \ "docker container start kamal-proxy", From da2a543cbcfa995265cb5583ee9e5802a58c5109 Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Wed, 9 Oct 2024 10:00:49 +0400 Subject: [PATCH 11/26] Reverted network arguments everywhere except to accessory config --- lib/kamal/commands/app.rb | 2 +- lib/kamal/commands/app/execution.rb | 2 +- lib/kamal/commands/proxy.rb | 2 +- lib/kamal/configuration.rb | 9 --------- lib/kamal/configuration/docs/configuration.yml | 7 ------- lib/kamal/configuration/docs/proxy.yml | 7 ------- lib/kamal/configuration/proxy.rb | 9 --------- test/commands/app_test.rb | 8 -------- test/commands/proxy_test.rb | 8 -------- test/configuration/proxy_test.rb | 9 --------- test/configuration_test.rb | 9 --------- 11 files changed, 3 insertions(+), 69 deletions(-) diff --git a/lib/kamal/commands/app.rb b/lib/kamal/commands/app.rb index 56a5656b..6d8f44c6 100644 --- a/lib/kamal/commands/app.rb +++ b/lib/kamal/commands/app.rb @@ -18,7 +18,7 @@ class Kamal::Commands::App < Kamal::Commands::Base "--detach", "--restart unless-stopped", "--name", container_name, - *config.network_args, + "--network", "kamal", *([ "--hostname", hostname ] if hostname), "-e", "KAMAL_CONTAINER_NAME=\"#{container_name}\"", "-e", "KAMAL_VERSION=\"#{config.version}\"", diff --git a/lib/kamal/commands/app/execution.rb b/lib/kamal/commands/app/execution.rb index 5770f7aa..4434c26a 100644 --- a/lib/kamal/commands/app/execution.rb +++ b/lib/kamal/commands/app/execution.rb @@ -11,7 +11,7 @@ module Kamal::Commands::App::Execution docker :run, ("-it" if interactive), "--rm", - *config.network_args, + "--network", "kamal", *role&.env_args(host), *argumentize("--env", env), *config.volume_args, diff --git a/lib/kamal/commands/proxy.rb b/lib/kamal/commands/proxy.rb index 3399531f..acff3dbd 100644 --- a/lib/kamal/commands/proxy.rb +++ b/lib/kamal/commands/proxy.rb @@ -4,7 +4,7 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base def run docker :run, "--name", container_name, - *config.network_args, + "--network", "kamal", "--detach", "--restart", "unless-stopped", "--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index b26c30c9..09f1ed89 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -18,7 +18,6 @@ class Kamal::Configuration PROXY_HTTP_PORT = 80 PROXY_HTTPS_PORT = 443 PROXY_LOG_MAX_SIZE = "10m" - NETWORK = "kamal" class << self def create_from(config_file:, destination: nil, version: nil) @@ -194,10 +193,6 @@ class Kamal::Configuration logging.args end - def network_args - argumentize "--network", network - end - def readiness_delay raw_config.readiness_delay || 7 @@ -302,10 +297,6 @@ class Kamal::Configuration end private - def network - raw_config["network"] || NETWORK - end - # Will raise ArgumentError if any required config keys are missing def ensure_destination_if_required if require_destination? && destination.nil? diff --git a/lib/kamal/configuration/docs/configuration.yml b/lib/kamal/configuration/docs/configuration.yml index b59394a3..6b059346 100644 --- a/lib/kamal/configuration/docs/configuration.yml +++ b/lib/kamal/configuration/docs/configuration.yml @@ -176,10 +176,3 @@ logging: # Alias configuration, see kamal docs alias: aliases: ... - -# Network -# -# The network the application will be attached to. -# -# Defaults to kamal: -network: custom diff --git a/lib/kamal/configuration/docs/proxy.yml b/lib/kamal/configuration/docs/proxy.yml index 0af14826..76ec3e41 100644 --- a/lib/kamal/configuration/docs/proxy.yml +++ b/lib/kamal/configuration/docs/proxy.yml @@ -103,10 +103,3 @@ proxy: # By default, kamal-proxy will not forward the headers if the `ssl` option is set to `true`, and # will forward them if it is set to `false`. forward_headers: true - - # Network - # - # The network the proxy container will be attached to. - # - # Defaults to kamal: - network: custom diff --git a/lib/kamal/configuration/proxy.rb b/lib/kamal/configuration/proxy.rb index 99c7aa1f..6232c3e0 100644 --- a/lib/kamal/configuration/proxy.rb +++ b/lib/kamal/configuration/proxy.rb @@ -3,7 +3,6 @@ class Kamal::Configuration::Proxy DEFAULT_LOG_REQUEST_HEADERS = [ "Cache-Control", "Last-Modified", "User-Agent" ] CONTAINER_NAME = "kamal-proxy" - NETWORK = "kamal" delegate :argumentize, :optionize, to: Kamal::Utils @@ -52,10 +51,6 @@ class Kamal::Configuration::Proxy optionize ({ target: "#{target}:#{app_port}" }).merge(deploy_options), with: "=" end - def network_args - argumentize "--network", network - end - def merge(other) self.class.new config: config, proxy_config: proxy_config.deep_merge(other.proxy_config) end @@ -64,8 +59,4 @@ class Kamal::Configuration::Proxy def seconds_duration(value) value ? "#{value}s" : nil end - - def network - proxy_config["network"] || NETWORK - end end diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index 403e90d4..0e5cad79 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -64,14 +64,6 @@ class CommandsAppTest < ActiveSupport::TestCase new_command.run.join(" ") end - test "run in custom network" do - @config[:network] = "custom" - - assert_equal \ - "docker run --detach --restart unless-stopped --name app-web-999 --network custom -e KAMAL_CONTAINER_NAME=\"app-web-999\" -e KAMAL_VERSION=\"999\" --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" --label service=\"app\" --label role=\"web\" --label destination dhh/app:999", - new_command.run.join(" ") - end - test "start" do assert_equal \ "docker start app-web-999", diff --git a/test/commands/proxy_test.rb b/test/commands/proxy_test.rb index 80f420d2..b7cc9f3d 100644 --- a/test/commands/proxy_test.rb +++ b/test/commands/proxy_test.rb @@ -27,14 +27,6 @@ class CommandsProxyTest < ActiveSupport::TestCase new_command.run.join(" ") end - test "run in custom network" do - @config[:network] = "custom" - - assert_equal \ - "docker run --name kamal-proxy --network custom --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy $(cat .kamal/proxy/options || echo \"--publish 80:80 --publish 443:443\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION}", - new_command.run.join(" ") - end - test "proxy start" do assert_equal \ "docker container start kamal-proxy", diff --git a/test/configuration/proxy_test.rb b/test/configuration/proxy_test.rb index 562c229f..588e5a35 100644 --- a/test/configuration/proxy_test.rb +++ b/test/configuration/proxy_test.rb @@ -38,15 +38,6 @@ class ConfigurationProxyTest < ActiveSupport::TestCase assert_not config.proxy.ssl? end - test "network_args defaults" do - assert_equal [ "--network", "kamal" ], config.proxy.network_args - end - - test "network_args with configured options" do - @deploy[:proxy] = { "network" => "example" } - assert_equal [ "--network", "example" ], config.proxy.network_args - end - private def config Kamal::Configuration.new(@deploy) diff --git a/test/configuration_test.rb b/test/configuration_test.rb index da53ddb6..c1aaa697 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -217,15 +217,6 @@ class ConfigurationTest < ActiveSupport::TestCase assert_equal [ "--log-driver", "\"local\"", "--log-opt", "max-size=\"100m\"", "--log-opt", "max-file=\"5\"" ], config.logging_args end - test "network_args default" do - assert_equal [ "--network", "kamal" ], @config.network_args - end - - test "network_args with configured options" do - config = Kamal::Configuration.new(@deploy.tap { |c| c.merge!(network: "custom") }) - assert_equal [ "--network", "custom" ], config.network_args - end - test "erb evaluation of yml config" do config = Kamal::Configuration.create_from config_file: Pathname.new(File.expand_path("fixtures/deploy.erb.yml", __dir__)) assert_equal "my-user", config.registry.username From 69b13ebc6a63ac00aaf126eedefa92344ff6b2a5 Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Wed, 2 Oct 2024 19:27:08 +0400 Subject: [PATCH 12/26] Renamed NETWORK to DEFAULT_NETWORK --- lib/kamal/configuration/accessory.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/kamal/configuration/accessory.rb b/lib/kamal/configuration/accessory.rb index 7aed80ea..3258c9d0 100644 --- a/lib/kamal/configuration/accessory.rb +++ b/lib/kamal/configuration/accessory.rb @@ -1,7 +1,7 @@ class Kamal::Configuration::Accessory include Kamal::Configuration::Validation - NETWORK = "kamal" + DEFAULT_NETWORK = "kamal" delegate :argumentize, :optionize, to: Kamal::Utils @@ -181,6 +181,6 @@ class Kamal::Configuration::Accessory end def network - accessory_config["network"] || NETWORK + accessory_config["network"] || DEFAULT_NETWORK end end From 844e3acf50a9767611153866da07e9d000eb3376 Mon Sep 17 00:00:00 2001 From: Alan Oliveira Date: Tue, 15 Oct 2024 14:24:09 +0900 Subject: [PATCH 13/26] prevent escape '#' when generating env_file string --- lib/kamal/env_file.rb | 4 +++- test/env_file_test.rb | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/kamal/env_file.rb b/lib/kamal/env_file.rb index 6a4a80e3..36c251be 100644 --- a/lib/kamal/env_file.rb +++ b/lib/kamal/env_file.rb @@ -37,6 +37,8 @@ class Kamal::EnvFile def escape_docker_env_file_ascii_value(value) # Doublequotes are treated literally in docker env files # so remove leading and trailing ones and unescape any others - value.to_s.dump[1..-2].gsub(/\\"/, "\"") + value.to_s.dump[1..-2] + .gsub(/\\"/, "\"") + .gsub(/\\#/, "#") end end diff --git a/test/env_file_test.rb b/test/env_file_test.rb index c6b9e66e..26344934 100644 --- a/test/env_file_test.rb +++ b/test/env_file_test.rb @@ -11,6 +11,16 @@ class EnvFileTest < ActiveSupport::TestCase Kamal::EnvFile.new(env).to_s end + test "to_s won't escape '#'" do + env = { + "foo" => "\#$foo", + "bar" => "\#{bar}" + } + + assert_equal "foo=\#$foo\nbar=\#{bar}\n", \ + Kamal::EnvFile.new(env).to_s + end + test "to_str won't escape chinese characters" do env = { "foo" => '你好 means hello, "欢迎" means welcome, that\'s simple! 😃 {smile}' From 0f3786781ba6674defb56bc2a72bec2a70030b55 Mon Sep 17 00:00:00 2001 From: Jonas Pardeyke Date: Tue, 15 Oct 2024 22:47:08 +0200 Subject: [PATCH 14/26] added `kamal proxy reboot` to raised error --- lib/kamal/cli/proxy.rb | 2 +- test/cli/proxy_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/kamal/cli/proxy.rb b/lib/kamal/cli/proxy.rb index 2ce7c2ac..7d226605 100644 --- a/lib/kamal/cli/proxy.rb +++ b/lib/kamal/cli/proxy.rb @@ -14,7 +14,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base version = capture_with_info(*KAMAL.proxy.version).strip.presence if version && Kamal::Utils.older_version?(version, Kamal::Configuration::PROXY_MINIMUM_VERSION) - raise "kamal-proxy version #{version} is too old, please reboot to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}" + raise "kamal-proxy version #{version} is too old, please reboot to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}. Run `kamal proxy reboot`." end execute *KAMAL.proxy.start_or_run end diff --git a/test/cli/proxy_test.rb b/test/cli/proxy_test.rb index c62589fe..97287ed0 100644 --- a/test/cli/proxy_test.rb +++ b/test/cli/proxy_test.rb @@ -22,7 +22,7 @@ class CliProxyTest < CliTestCase end end - assert_includes exception.message, "kamal-proxy version v0.0.1 is too old, please reboot to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}" + assert_includes exception.message, "kamal-proxy version v0.0.1 is too old, please reboot to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}. Run `kamal proxy reboot`." ensure Thread.report_on_exception = false end From 8cec17dd058dbf446e67d7b85807a78c0dfc8309 Mon Sep 17 00:00:00 2001 From: Kyle Rippey Date: Tue, 15 Oct 2024 23:20:18 -0700 Subject: [PATCH 15/26] Made secret adapters raise a meaningful error if the required CLI is not installed --- lib/kamal/secrets/adapters/base.rb | 5 +++++ lib/kamal/secrets/adapters/bitwarden.rb | 9 +++++++++ lib/kamal/secrets/adapters/last_pass.rb | 9 +++++++++ lib/kamal/secrets/adapters/one_password.rb | 9 +++++++++ lib/kamal/secrets/adapters/test.rb | 4 ++++ test/secrets/bitwarden_adapter_test.rb | 23 ++++++++++++++++++++++ test/secrets/last_pass_adapter_test.rb | 13 ++++++++++++ test/secrets/one_password_adapter_test.rb | 15 ++++++++++++++ 8 files changed, 87 insertions(+) diff --git a/lib/kamal/secrets/adapters/base.rb b/lib/kamal/secrets/adapters/base.rb index 97b2a458..579414af 100644 --- a/lib/kamal/secrets/adapters/base.rb +++ b/lib/kamal/secrets/adapters/base.rb @@ -2,6 +2,7 @@ class Kamal::Secrets::Adapters::Base delegate :optionize, to: Kamal::Utils def fetch(secrets, account:, from: nil) + check_dependencies! session = login(account) full_secrets = secrets.map { |secret| [ from, secret ].compact.join("/") } fetch_secrets(full_secrets, account: account, session: session) @@ -15,4 +16,8 @@ class Kamal::Secrets::Adapters::Base def fetch_secrets(...) raise NotImplementedError end + + def check_dependencies! + raise NotImplementedError + end end diff --git a/lib/kamal/secrets/adapters/bitwarden.rb b/lib/kamal/secrets/adapters/bitwarden.rb index e84a0d93..7ea4f6f7 100644 --- a/lib/kamal/secrets/adapters/bitwarden.rb +++ b/lib/kamal/secrets/adapters/bitwarden.rb @@ -63,4 +63,13 @@ class Kamal::Secrets::Adapters::Bitwarden < Kamal::Secrets::Adapters::Base result = `#{full_command}`.strip raw ? result : JSON.parse(result) end + + def check_dependencies! + raise RuntimeError, "Bitwarden CLI is not installed" unless cli_installed? + end + + def cli_installed? + `bw --version 2> /dev/null` + $?.success? + end end diff --git a/lib/kamal/secrets/adapters/last_pass.rb b/lib/kamal/secrets/adapters/last_pass.rb index 390e84ed..2f95148b 100644 --- a/lib/kamal/secrets/adapters/last_pass.rb +++ b/lib/kamal/secrets/adapters/last_pass.rb @@ -27,4 +27,13 @@ class Kamal::Secrets::Adapters::LastPass < Kamal::Secrets::Adapters::Base end end end + + def check_dependencies! + raise RuntimeError, "LastPass CLI is not installed" unless cli_installed? + end + + def cli_installed? + `lpass --version 2> /dev/null` + $?.success? + end end diff --git a/lib/kamal/secrets/adapters/one_password.rb b/lib/kamal/secrets/adapters/one_password.rb index c7e9b28d..c7f9d5ab 100644 --- a/lib/kamal/secrets/adapters/one_password.rb +++ b/lib/kamal/secrets/adapters/one_password.rb @@ -58,4 +58,13 @@ class Kamal::Secrets::Adapters::OnePassword < Kamal::Secrets::Adapters::Base raise RuntimeError, "Could not read #{fields.join(", ")} from #{item} in the #{vault} 1Password vault" unless $?.success? end end + + def check_dependencies! + raise RuntimeError, "1Password CLI is not installed" unless cli_installed? + end + + def cli_installed? + `op --version 2> /dev/null` + $?.success? + end end diff --git a/lib/kamal/secrets/adapters/test.rb b/lib/kamal/secrets/adapters/test.rb index fc0903d9..82577a76 100644 --- a/lib/kamal/secrets/adapters/test.rb +++ b/lib/kamal/secrets/adapters/test.rb @@ -7,4 +7,8 @@ class Kamal::Secrets::Adapters::Test < Kamal::Secrets::Adapters::Base def fetch_secrets(secrets, account:, session:) secrets.to_h { |secret| [ secret, secret.reverse ] } end + + def check_dependencies! + # no op + end end diff --git a/test/secrets/bitwarden_adapter_test.rb b/test/secrets/bitwarden_adapter_test.rb index e2a3ac37..2bc871d3 100644 --- a/test/secrets/bitwarden_adapter_test.rb +++ b/test/secrets/bitwarden_adapter_test.rb @@ -2,6 +2,8 @@ require "test_helper" class BitwardenAdapterTest < SecretAdapterTestCase test "fetch" do + stub_ticks.with("bw --version 2> /dev/null") + stub_unlocked stub_ticks.with("bw sync").returns("") stub_mypassword @@ -14,6 +16,8 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch with no login" do + stub_ticks.with("bw --version 2> /dev/null") + stub_unlocked stub_ticks.with("bw sync").returns("") stub_noteitem @@ -25,6 +29,8 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch with from" do + stub_ticks.with("bw --version 2> /dev/null") + stub_unlocked stub_ticks.with("bw sync").returns("") stub_myitem @@ -39,6 +45,8 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch with multiple items" do + stub_ticks.with("bw --version 2> /dev/null") + stub_unlocked stub_ticks.with("bw sync").returns("") @@ -80,6 +88,8 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch unauthenticated" do + stub_ticks.with("bw --version 2> /dev/null") + stub_ticks .with("bw status") .returns( @@ -101,6 +111,8 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch locked" do + stub_ticks.with("bw --version 2> /dev/null") + stub_ticks .with("bw status") .returns( @@ -126,6 +138,8 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch locked with session" do + stub_ticks.with("bw --version 2> /dev/null") + stub_ticks .with("bw status") .returns( @@ -150,6 +164,15 @@ class BitwardenAdapterTest < SecretAdapterTestCase assert_equal expected_json, json end + test "fetch without CLI installed" do + stub_ticks_with("bw --version 2> /dev/null", succeed: false) + + error = assert_raises RuntimeError do + JSON.parse(shellunescape(run_command("fetch", "mynote"))) + end + assert_equal "Bitwarden CLI is not installed", error.message + end + private def run_command(*command) stdouted do diff --git a/test/secrets/last_pass_adapter_test.rb b/test/secrets/last_pass_adapter_test.rb index 3801d486..ca1f346c 100644 --- a/test/secrets/last_pass_adapter_test.rb +++ b/test/secrets/last_pass_adapter_test.rb @@ -6,6 +6,7 @@ class LastPassAdapterTest < SecretAdapterTestCase end test "fetch" do + stub_ticks.with("lpass --version 2> /dev/null") stub_ticks.with("lpass status --color never").returns("Logged in as email@example.com.") stub_ticks @@ -63,6 +64,7 @@ class LastPassAdapterTest < SecretAdapterTestCase end test "fetch with from" do + stub_ticks.with("lpass --version 2> /dev/null") stub_ticks.with("lpass status --color never").returns("Logged in as email@example.com.") stub_ticks @@ -107,6 +109,8 @@ class LastPassAdapterTest < SecretAdapterTestCase end test "fetch with signin" do + stub_ticks.with("lpass --version 2> /dev/null") + stub_ticks_with("lpass status --color never", succeed: false).returns("Not logged in.") stub_ticks_with("lpass login email@example.com", succeed: true).returns("") stub_ticks.with("lpass show SECRET1 --json").returns(single_item_json) @@ -120,6 +124,15 @@ class LastPassAdapterTest < SecretAdapterTestCase assert_equal expected_json, json end + test "fetch without CLI installed" do + stub_ticks_with("lpass --version 2> /dev/null", succeed: false) + + error = assert_raises RuntimeError do + JSON.parse(shellunescape(run_command("fetch", "SECRET1", "FOLDER1/FSECRET1", "FOLDER1/FSECRET2"))) + end + assert_equal "LastPass CLI is not installed", error.message + end + private def run_command(*command) stdouted do diff --git a/test/secrets/one_password_adapter_test.rb b/test/secrets/one_password_adapter_test.rb index 59ad511d..36fab7c3 100644 --- a/test/secrets/one_password_adapter_test.rb +++ b/test/secrets/one_password_adapter_test.rb @@ -2,6 +2,7 @@ require "test_helper" class SecretsOnePasswordAdapterTest < SecretAdapterTestCase test "fetch" do + stub_ticks.with("op --version 2> /dev/null") stub_ticks.with("op account get --account myaccount 2> /dev/null") stub_ticks @@ -56,6 +57,7 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase end test "fetch with multiple items" do + stub_ticks.with("op --version 2> /dev/null") stub_ticks.with("op account get --account myaccount 2> /dev/null") stub_ticks @@ -115,6 +117,8 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase end test "fetch with signin, no session" do + stub_ticks.with("op --version 2> /dev/null") + stub_ticks_with("op account get --account myaccount 2> /dev/null", succeed: false) stub_ticks_with("op signin --account \"myaccount\" --force --raw", succeed: true).returns("") @@ -132,6 +136,8 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase end test "fetch with signin and session" do + stub_ticks.with("op --version 2> /dev/null") + stub_ticks_with("op account get --account myaccount 2> /dev/null", succeed: false) stub_ticks_with("op signin --account \"myaccount\" --force --raw", succeed: true).returns("1234567890") @@ -148,6 +154,15 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase assert_equal expected_json, json end + test "fetch without CLI installed" do + stub_ticks_with("op --version 2> /dev/null", succeed: false) + + error = assert_raises RuntimeError do + JSON.parse(shellunescape(run_command("fetch", "--from", "op://myvault/myitem", "section/SECRET1", "section/SECRET2", "section2/SECRET3"))) + end + assert_equal "1Password CLI is not installed", error.message + end + private def run_command(*command) stdouted do From e362b0106a931c0a22eab4647b68d9dcb4c79ec0 Mon Sep 17 00:00:00 2001 From: Jonas Pardeyke Date: Wed, 16 Oct 2024 09:08:30 +0200 Subject: [PATCH 16/26] changed text --- lib/kamal/cli/proxy.rb | 2 +- test/cli/proxy_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/kamal/cli/proxy.rb b/lib/kamal/cli/proxy.rb index 7d226605..d0e9ba2b 100644 --- a/lib/kamal/cli/proxy.rb +++ b/lib/kamal/cli/proxy.rb @@ -14,7 +14,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base version = capture_with_info(*KAMAL.proxy.version).strip.presence if version && Kamal::Utils.older_version?(version, Kamal::Configuration::PROXY_MINIMUM_VERSION) - raise "kamal-proxy version #{version} is too old, please reboot to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}. Run `kamal proxy reboot`." + raise "kamal-proxy version #{version} is too old, run `kamal proxy reboot` in order to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}" end execute *KAMAL.proxy.start_or_run end diff --git a/test/cli/proxy_test.rb b/test/cli/proxy_test.rb index 97287ed0..9fe8f56c 100644 --- a/test/cli/proxy_test.rb +++ b/test/cli/proxy_test.rb @@ -22,7 +22,7 @@ class CliProxyTest < CliTestCase end end - assert_includes exception.message, "kamal-proxy version v0.0.1 is too old, please reboot to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}. Run `kamal proxy reboot`." + assert_includes exception.message, "kamal-proxy version v0.0.1 is too old, run `kamal proxy reboot` in order to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}" ensure Thread.report_on_exception = false end From 6f08750c3e7e521e7694f9583befec83490902d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 11:29:41 -0700 Subject: [PATCH 17/26] Bump webrick from 1.8.1 to 1.8.2 in the bundler group across 1 directory (#1125) Bumps the bundler group with 1 update in the / directory: [webrick](https://github.com/ruby/webrick). Updates `webrick` from 1.8.1 to 1.8.2 - [Release notes](https://github.com/ruby/webrick/releases) - [Commits](https://github.com/ruby/webrick/compare/v1.8.1...v1.8.2) --- updated-dependencies: - dependency-name: webrick dependency-type: indirect dependency-group: bundler ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 093ef9b7..e637e7c0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -166,7 +166,7 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) - webrick (1.8.1) + webrick (1.8.2) zeitwerk (2.6.17) PLATFORMS From c0ca5e6dbb1701bf767e842872ce999c1b40ed76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 11:29:59 -0700 Subject: [PATCH 18/26] Bump rexml from 3.3.4 to 3.3.6 in the bundler group across 1 directory (#1126) Bumps the bundler group with 1 update in the / directory: [rexml](https://github.com/ruby/rexml). Updates `rexml` from 3.3.4 to 3.3.6 - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.3.4...v3.3.6) --- updated-dependencies: - dependency-name: rexml dependency-type: indirect dependency-group: bundler ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index e637e7c0..ad55ec15 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -122,7 +122,7 @@ GEM regexp_parser (2.9.2) reline (0.5.9) io-console (~> 0.5) - rexml (3.3.4) + rexml (3.3.6) strscan rubocop (1.65.1) json (~> 2.3) From 74a06b0ccda616c86ebe1729d0795f39bcac9f00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 11:30:14 -0700 Subject: [PATCH 19/26] Bump actionpack in the bundler group across 1 directory (#1127) Bumps the bundler group with 1 update in the / directory: [actionpack](https://github.com/rails/rails). Updates `actionpack` from 7.1.3.4 to 7.1.4.1 - [Release notes](https://github.com/rails/rails/releases) - [Changelog](https://github.com/rails/rails/blob/v7.2.1.1/actionpack/CHANGELOG.md) - [Commits](https://github.com/rails/rails/compare/v7.1.3.4...v7.1.4.1) --- updated-dependencies: - dependency-name: actionpack dependency-type: indirect dependency-group: bundler ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ad55ec15..8b497389 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -16,9 +16,9 @@ PATH GEM remote: https://rubygems.org/ specs: - actionpack (7.1.3.4) - actionview (= 7.1.3.4) - activesupport (= 7.1.3.4) + actionpack (7.1.4.1) + actionview (= 7.1.4.1) + activesupport (= 7.1.4.1) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -26,13 +26,13 @@ GEM rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actionview (7.1.3.4) - activesupport (= 7.1.3.4) + actionview (7.1.4.1) + activesupport (= 7.1.4.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activesupport (7.1.3.4) + activesupport (7.1.4.1) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -49,7 +49,7 @@ GEM bcrypt_pbkdf (1.1.1-x86_64-darwin) bigdecimal (3.1.8) builder (3.3.0) - concurrent-ruby (1.3.3) + concurrent-ruby (1.3.4) connection_pool (2.4.1) crass (1.0.6) debug (1.9.2) @@ -59,7 +59,7 @@ GEM drb (2.2.1) ed25519 (1.3.0) erubi (1.13.0) - i18n (1.14.5) + i18n (1.14.6) concurrent-ruby (~> 1.0) io-console (0.7.2) irb (1.14.0) @@ -70,7 +70,7 @@ GEM loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) - minitest (5.24.1) + minitest (5.25.1) mocha (2.4.5) ruby2_keywords (>= 0.0.5) mutex_m (0.2.0) @@ -92,7 +92,7 @@ GEM psych (5.1.2) stringio racc (1.8.1) - rack (3.1.7) + rack (3.1.8) rack-session (2.0.0) rack (>= 3.0.0) rack-test (2.1.0) @@ -107,9 +107,9 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.1.3.4) - actionpack (= 7.1.3.4) - activesupport (= 7.1.3.4) + railties (7.1.4.1) + actionpack (= 7.1.4.1) + activesupport (= 7.1.4.1) irb rackup (>= 1.0.0) rake (>= 12.2) From c320343bb23dee027e7591b7829cb203e67ea850 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Sat, 19 Oct 2024 18:18:34 +0100 Subject: [PATCH 20/26] Updated secrets error message if secrets files do not exist --- lib/kamal/secrets.rb | 17 +++++++++++------ test/secrets_test.rb | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/kamal/secrets.rb b/lib/kamal/secrets.rb index c7d4cc03..7a382f98 100644 --- a/lib/kamal/secrets.rb +++ b/lib/kamal/secrets.rb @@ -1,13 +1,10 @@ require "dotenv" class Kamal::Secrets - attr_reader :secrets_files - Kamal::Secrets::Dotenv::InlineCommandSubstitution.install! def initialize(destination: nil) - @secrets_files = \ - [ ".kamal/secrets-common", ".kamal/secrets#{(".#{destination}" if destination)}" ].select { |f| File.exist?(f) } + @destination = destination @mutex = Mutex.new end @@ -17,10 +14,10 @@ class Kamal::Secrets secrets.fetch(key) end rescue KeyError - if secrets_files + if secrets_files.present? raise Kamal::ConfigurationError, "Secret '#{key}' not found in #{secrets_files.join(", ")}" else - raise Kamal::ConfigurationError, "Secret '#{key}' not found, no secret files provided" + raise Kamal::ConfigurationError, "Secret '#{key}' not found, no secret files (#{secrets_filenames.join(", ")}) provided" end end @@ -28,10 +25,18 @@ class Kamal::Secrets secrets end + def secrets_files + @secrets_files ||= secrets_filenames.select { |f| File.exist?(f) } + end + private def secrets @secrets ||= secrets_files.inject({}) do |secrets, secrets_file| secrets.merge!(::Dotenv.parse(secrets_file)) end end + + def secrets_filenames + [ ".kamal/secrets-common", ".kamal/secrets#{(".#{@destination}" if @destination)}" ] + end end diff --git a/test/secrets_test.rb b/test/secrets_test.rb index bb77a196..aca9cebe 100644 --- a/test/secrets_test.rb +++ b/test/secrets_test.rb @@ -31,4 +31,18 @@ class SecretsTest < ActiveSupport::TestCase assert_equal "JKL", Kamal::Secrets.new(destination: "nodest")["SECRET2"] end end + + test "no secrets files" do + with_test_secrets do + error = assert_raises(Kamal::ConfigurationError) do + Kamal::Secrets.new["SECRET"] + end + assert_equal "Secret 'SECRET' not found, no secret files (.kamal/secrets-common, .kamal/secrets) provided", error.message + + error = assert_raises(Kamal::ConfigurationError) do + Kamal::Secrets.new(destination: "dest")["SECRET"] + end + assert_equal "Secret 'SECRET' not found, no secret files (.kamal/secrets-common, .kamal/secrets.dest) provided", error.message + end + end end From 3ee45d7b30eef1479e14e8ec0499ca643c737392 Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Tue, 22 Oct 2024 12:38:07 +0100 Subject: [PATCH 21/26] Require zeitwerk 2.6.12 We were requiring Zeitwerk 2.5+, but calling eager_load_namespace which was added in 2.6.2. Fixes: https://github.com/basecamp/kamal/issues/1109 --- Gemfile.lock | 4 ++-- kamal.gemspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8b497389..1f825a11 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ PATH net-ssh (~> 7.0) sshkit (>= 1.23.0, < 2.0) thor (~> 1.3) - zeitwerk (~> 2.5) + zeitwerk (>= 2.6.18, < 3.0) GEM remote: https://rubygems.org/ @@ -167,7 +167,7 @@ GEM concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) webrick (1.8.2) - zeitwerk (2.6.17) + zeitwerk (2.7.1) PLATFORMS arm64-darwin diff --git a/kamal.gemspec b/kamal.gemspec index 0dfab60b..c1a8dbeb 100644 --- a/kamal.gemspec +++ b/kamal.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |spec| spec.add_dependency "net-ssh", "~> 7.0" spec.add_dependency "thor", "~> 1.3" spec.add_dependency "dotenv", "~> 3.1" - spec.add_dependency "zeitwerk", "~> 2.5" + spec.add_dependency "zeitwerk", ">= 2.6.18", "< 3.0" spec.add_dependency "ed25519", "~> 1.2" spec.add_dependency "bcrypt_pbkdf", "~> 1.0" spec.add_dependency "concurrent-ruby", "~> 1.2" From a3f58307283223b9a32726ff92a504eed3067843 Mon Sep 17 00:00:00 2001 From: Alan Oliveira Date: Wed, 23 Oct 2024 08:06:24 +0900 Subject: [PATCH 22/26] improve test legibility --- test/env_file_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/env_file_test.rb b/test/env_file_test.rb index 26344934..34d31ad6 100644 --- a/test/env_file_test.rb +++ b/test/env_file_test.rb @@ -13,8 +13,8 @@ class EnvFileTest < ActiveSupport::TestCase test "to_s won't escape '#'" do env = { - "foo" => "\#$foo", - "bar" => "\#{bar}" + "foo" => '#$foo', + "bar" => '#{bar}' } assert_equal "foo=\#$foo\nbar=\#{bar}\n", \ From 7142534e77d244dc3fb98acb5f74f0544082fbf2 Mon Sep 17 00:00:00 2001 From: Jan Sterba Date: Sat, 5 Oct 2024 16:05:28 +0200 Subject: [PATCH 23/26] [bitwarden] ability to fetch all fields from an item Sometimes a projects has a lot of secrets (more than 10). And its cumbersome to write $(kama secrets fetch ...) with a lot of field names. I want to be able to just fetch all the fields from a given item and then just use these with $(kamal extract NAME) --- lib/kamal/secrets/adapters/bitwarden.rb | 22 +++++++---- test/secrets/bitwarden_adapter_test.rb | 52 ++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/lib/kamal/secrets/adapters/bitwarden.rb b/lib/kamal/secrets/adapters/bitwarden.rb index 7ea4f6f7..5dfb72db 100644 --- a/lib/kamal/secrets/adapters/bitwarden.rb +++ b/lib/kamal/secrets/adapters/bitwarden.rb @@ -25,18 +25,15 @@ class Kamal::Secrets::Adapters::Bitwarden < Kamal::Secrets::Adapters::Base {}.tap do |results| items_fields(secrets).each do |item, fields| item_json = run_command("get item #{item.shellescape}", session: session, raw: true) - raise RuntimeError, "Could not read #{secret} from Bitwarden" unless $?.success? + raise RuntimeError, "Could not read #{item} from Bitwarden" unless $?.success? item_json = JSON.parse(item_json) - if fields.any? - fields.each do |field| - item_field = item_json["fields"].find { |f| f["name"] == field } - raise RuntimeError, "Could not find field #{field} in item #{item} in Bitwarden" unless item_field - value = item_field["value"] - results["#{item}/#{field}"] = value - end + results.merge! fetch_secrets_from_fields(fields, item, item_json) elsif item_json.dig("login", "password") results[item] = item_json.dig("login", "password") + elsif item_json["fields"]&.any? + fields = item_json["fields"].pluck("name") + results.merge! fetch_secrets_from_fields(fields, item, item_json) else raise RuntimeError, "Item #{item} is not a login type item and no fields were specified" end @@ -44,6 +41,15 @@ class Kamal::Secrets::Adapters::Bitwarden < Kamal::Secrets::Adapters::Base end end + def fetch_secrets_from_fields(fields, item, item_json) + fields.to_h do |field| + item_field = item_json["fields"].find { |f| f["name"] == field } + raise RuntimeError, "Could not find field #{field} in item #{item} in Bitwarden" unless item_field + value = item_field["value"] + [ "#{item}/#{field}", value ] + end + end + def items_fields(secrets) {}.tap do |items| secrets.each do |secret| diff --git a/test/secrets/bitwarden_adapter_test.rb b/test/secrets/bitwarden_adapter_test.rb index 2bc871d3..ad280791 100644 --- a/test/secrets/bitwarden_adapter_test.rb +++ b/test/secrets/bitwarden_adapter_test.rb @@ -44,6 +44,23 @@ class BitwardenAdapterTest < SecretAdapterTestCase assert_equal expected_json, json end + test "fetch all with from" do + stub_ticks.with("bw --version 2> /dev/null") + + stub_unlocked + stub_ticks.with("bw sync").returns("") + stub_noteitem_with_fields + + json = JSON.parse(shellunescape(run_command("fetch", "mynotefields"))) + + expected_json = { + "mynotefields/field1"=>"secret1", "mynotefields/field2"=>"blam", "mynotefields/field3"=>"fewgrwjgk", + "mynotefields/field4"=>"auto" + } + + assert_equal expected_json, json + end + test "fetch with multiple items" do stub_ticks.with("bw --version 2> /dev/null") @@ -237,7 +254,37 @@ class BitwardenAdapterTest < SecretAdapterTestCase "collectionIds":[] } JSON - end + end + + def stub_noteitem_with_fields(session: nil) + stub_ticks + .with("#{"BW_SESSION=#{session} " if session}bw get item mynotefields") + .returns(<<~JSON) + { + "passwordHistory":null, + "revisionDate":"2024-09-28T09:07:27.461Z", + "creationDate":"2024-09-28T09:07:00.740Z", + "deletedDate":null, + "object":"item", + "id":"aaaaaaaa-cccc-eeee-0000-222222222222", + "organizationId":null, + "folderId":null, + "type":2, + "reprompt":0, + "name":"noteitem", + "notes":"NOTES", + "favorite":false, + "fields":[ + {"name":"field1","value":"secret1","type":1,"linkedId":null}, + {"name":"field2","value":"blam","type":1,"linkedId":null}, + {"name":"field3","value":"fewgrwjgk","type":1,"linkedId":null}, + {"name":"field4","value":"auto","type":1,"linkedId":null} + ], + "secureNote":{"type":0}, + "collectionIds":[] + } + JSON + end def stub_myitem stub_ticks @@ -260,7 +307,8 @@ class BitwardenAdapterTest < SecretAdapterTestCase "fields":[ {"name":"field1","value":"secret1","type":1,"linkedId":null}, {"name":"field2","value":"blam","type":1,"linkedId":null}, - {"name":"field3","value":"fewgrwjgk","type":1,"linkedId":null} + {"name":"field3","value":"fewgrwjgk","type":1,"linkedId":null}, + {"name":"field4","value":"auto","type":1,"linkedId":null} ], "login":{"fido2Credentials":[],"uris":[],"username":null,"password":null,"totp":null,"passwordRevisionDate":null},"collectionIds":[] } From 8d0f4903ae87c07ca7595eefea97600ab2fee465 Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Wed, 23 Oct 2024 14:56:53 +0100 Subject: [PATCH 24/26] Ensure using at least net-ssh 7.3.0 This has support for aes(128|256)gcm ciphers and some fixes for Ruby 3.3. --- Gemfile.lock | 4 ++-- kamal.gemspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1f825a11..3e2f89a4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ PATH concurrent-ruby (~> 1.2) dotenv (~> 3.1) ed25519 (~> 1.2) - net-ssh (~> 7.0) + net-ssh (~> 7.3) sshkit (>= 1.23.0, < 2.0) thor (~> 1.3) zeitwerk (>= 2.6.18, < 3.0) @@ -78,7 +78,7 @@ GEM net-ssh (>= 2.6.5, < 8.0.0) net-sftp (4.0.0) net-ssh (>= 5.0.0, < 8.0.0) - net-ssh (7.2.3) + net-ssh (7.3.0) nokogiri (1.16.7-arm64-darwin) racc (~> 1.4) nokogiri (1.16.7-x86_64-darwin) diff --git a/kamal.gemspec b/kamal.gemspec index c1a8dbeb..7218f865 100644 --- a/kamal.gemspec +++ b/kamal.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |spec| spec.add_dependency "activesupport", ">= 7.0" spec.add_dependency "sshkit", ">= 1.23.0", "< 2.0" - spec.add_dependency "net-ssh", "~> 7.0" + spec.add_dependency "net-ssh", "~> 7.3" spec.add_dependency "thor", "~> 1.3" spec.add_dependency "dotenv", "~> 3.1" spec.add_dependency "zeitwerk", ">= 2.6.18", "< 3.0" From 9a8a45015b881aed34e7b35197b1249487afe413 Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Wed, 23 Oct 2024 15:05:20 +0100 Subject: [PATCH 25/26] Allow log max size to not be set The max-size log opt is not valid for all logging drivers, such as syslog. Allow the option to be removed from the boot config with: ``` kamal proxy boot_config set --log-max-size= or kamal proxy boot_config set --log-max-size="" ``` --- lib/kamal/cli/proxy.rb | 1 + lib/kamal/configuration.rb | 2 +- test/cli/proxy_test.rb | 9 +++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/kamal/cli/proxy.rb b/lib/kamal/cli/proxy.rb index d0e9ba2b..d985e73e 100644 --- a/lib/kamal/cli/proxy.rb +++ b/lib/kamal/cli/proxy.rb @@ -37,6 +37,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base ] on(KAMAL.proxy_hosts) do |host| + p boot_options execute(*KAMAL.proxy.ensure_proxy_directory) upload! StringIO.new(boot_options.join(" ")), KAMAL.config.proxy_options_file end diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index 86602fe1..eba09657 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -254,7 +254,7 @@ class Kamal::Configuration end def proxy_logging_args(max_size) - argumentize "--log-opt", "max-size=#{max_size}" + argumentize "--log-opt", "max-size=#{max_size}" if max_size.present? end def proxy_options_default diff --git a/test/cli/proxy_test.rb b/test/cli/proxy_test.rb index 9fe8f56c..0a890451 100644 --- a/test/cli/proxy_test.rb +++ b/test/cli/proxy_test.rb @@ -263,6 +263,15 @@ class CliProxyTest < CliTestCase end end + test "boot_config set no log max size" do + run_command("boot_config", "set", "--log-max-size=").tap do |output| + %w[ 1.1.1.1 1.1.1.2 ].each do |host| + assert_match "Running /usr/bin/env mkdir -p .kamal/proxy on #{host}", output + assert_match "Uploading \"--publish 80:80 --publish 443:443\" to .kamal/proxy/options on #{host}", output + end + end + end + test "boot_config set custom ports" do run_command("boot_config", "set", "--http-port", "8080", "--https-port", "8443").tap do |output| %w[ 1.1.1.1 1.1.1.2 ].each do |host| From 1980a79e737f83c0c73a0c3099ca36291bdc3b5c Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Fri, 25 Oct 2024 08:10:25 +0100 Subject: [PATCH 26/26] Update lib/kamal/cli/proxy.rb Co-authored-by: Sijawusz Pur Rahnama --- lib/kamal/cli/proxy.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/kamal/cli/proxy.rb b/lib/kamal/cli/proxy.rb index d985e73e..d0e9ba2b 100644 --- a/lib/kamal/cli/proxy.rb +++ b/lib/kamal/cli/proxy.rb @@ -37,7 +37,6 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base ] on(KAMAL.proxy_hosts) do |host| - p boot_options execute(*KAMAL.proxy.ensure_proxy_directory) upload! StringIO.new(boot_options.join(" ")), KAMAL.config.proxy_options_file end