From 403d186753a519b7c535a46efc30a9532d4e43de Mon Sep 17 00:00:00 2001 From: Dmytro Shteflyuk Date: Mon, 30 Sep 2024 17:33:32 -0400 Subject: [PATCH 1/2] Consolidated proxy-related configuration options and constants under Kamal::Configuration::Proxy --- lib/kamal/cli/proxy.rb | 12 ++++++------ lib/kamal/commands/app/proxy.rb | 4 +--- lib/kamal/commands/proxy.rb | 24 +++++++++++++----------- lib/kamal/configuration.rb | 29 ----------------------------- lib/kamal/configuration/proxy.rb | 28 ++++++++++++++++++++++++++++ test/cli/proxy_test.rb | 20 ++++++++++---------- test/commands/proxy_test.rb | 4 ++-- test/integration/main_test.rb | 2 +- 8 files changed, 61 insertions(+), 62 deletions(-) diff --git a/lib/kamal/cli/proxy.rb b/lib/kamal/cli/proxy.rb index 89fb2fd7..befc89f0 100644 --- a/lib/kamal/cli/proxy.rb +++ b/lib/kamal/cli/proxy.rb @@ -13,8 +13,8 @@ def boot 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}" + 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}" end execute *KAMAL.proxy.start_or_run end @@ -23,20 +23,20 @@ def boot desc "boot_config ", "Mange kamal-proxy boot configuration" option :publish, type: :boolean, default: true, desc: "Publish the proxy ports on the host" - option :http_port, type: :numeric, default: Kamal::Configuration::PROXY_HTTP_PORT, desc: "HTTP port to publish on the host" - option :https_port, type: :numeric, default: Kamal::Configuration::PROXY_HTTPS_PORT, desc: "HTTPS port to publish on the host" + option :http_port, type: :numeric, default: Kamal::Configuration::Proxy::HTTP_PORT, desc: "HTTP port to publish on the host" + option :https_port, type: :numeric, default: Kamal::Configuration::Proxy::HTTPS_PORT, desc: "HTTPS port to publish on the host" option :docker_options, type: :array, default: [], desc: "Docker options to pass to the proxy container", banner: "option=value option2=value2" def boot_config(subcommand) case subcommand when "set" boot_options = [ - *(KAMAL.config.proxy_publish_args(options[:http_port], options[:https_port]) if options[:publish]), + *(KAMAL.config.proxy.publish_args(options[:http_port], options[:https_port]) if options[:publish]), *options[:docker_options].map { |option| "--#{option}" } ] on(KAMAL.proxy_hosts) do |host| execute(*KAMAL.proxy.ensure_proxy_directory) - upload! StringIO.new(boot_options.join(" ")), KAMAL.config.proxy_options_file + upload! StringIO.new(boot_options.join(" ")), KAMAL.config.proxy.options_file end when "get" on(KAMAL.proxy_hosts) do |host| diff --git a/lib/kamal/commands/app/proxy.rb b/lib/kamal/commands/app/proxy.rb index 777a4aaf..2caead41 100644 --- a/lib/kamal/commands/app/proxy.rb +++ b/lib/kamal/commands/app/proxy.rb @@ -1,6 +1,4 @@ module Kamal::Commands::App::Proxy - delegate :proxy_container_name, to: :config - def deploy(target:) proxy_exec :deploy, role.container_prefix, *role.proxy.deploy_command_args(target: target) end @@ -11,6 +9,6 @@ def remove private def proxy_exec(*command) - docker :exec, proxy_container_name, "kamal-proxy", *command + docker :exec, config.proxy.container_name, "kamal-proxy", *command end end diff --git a/lib/kamal/commands/proxy.rb b/lib/kamal/commands/proxy.rb index acff3dbd..235cb1da 100644 --- a/lib/kamal/commands/proxy.rb +++ b/lib/kamal/commands/proxy.rb @@ -1,5 +1,12 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base - delegate :argumentize, :optionize, to: Kamal::Utils + attr_reader :proxy_config + delegate :image, :options_file, :directory, :container_name, :default_options, + to: :proxy_config + + def initialize(config) + super(config) + @proxy_config = config.proxy + end def run docker :run, @@ -9,7 +16,7 @@ def run "--restart", "unless-stopped", "--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", "\$\(#{get_boot_options.join(" ")}\)", - config.proxy_image + image end def start @@ -65,23 +72,18 @@ def cleanup_traefik end def ensure_proxy_directory - make_directory config.proxy_directory + make_directory directory end def remove_proxy_directory - remove_directory config.proxy_directory + remove_directory directory end def get_boot_options - combine [ :cat, config.proxy_options_file ], [ :echo, "\"#{config.proxy_options_default.join(" ")}\"" ], by: "||" + combine [ :cat, options_file ], [ :echo, "\"#{default_options.join(" ")}\"" ], by: "||" end def reset_boot_options - remove_file config.proxy_options_file + remove_file options_file end - - private - def container_name - config.proxy_container_name - end end diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index fb997949..6991308f 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -14,10 +14,6 @@ class Kamal::Configuration include Validation - PROXY_MINIMUM_VERSION = "v0.7.0" - PROXY_HTTP_PORT = 80 - PROXY_HTTPS_PORT = 443 - class << self def create_from(config_file:, destination: nil, version: nil) raw_config = load_config_files(config_file, *destination_config_file(config_file, destination)) @@ -246,31 +242,6 @@ def env_tag(name) env_tags.detect { |t| t.name == name.to_s } end - def proxy_publish_args(http_port, https_port) - argumentize "--publish", [ "#{http_port}:#{PROXY_HTTP_PORT}", "#{https_port}:#{PROXY_HTTPS_PORT}" ] - end - - def proxy_options_default - proxy_publish_args PROXY_HTTP_PORT, PROXY_HTTPS_PORT - end - - def proxy_image - "basecamp/kamal-proxy:#{PROXY_MINIMUM_VERSION}" - end - - def proxy_container_name - "kamal-proxy" - end - - def proxy_directory - File.join run_directory, "proxy" - end - - def proxy_options_file - File.join proxy_directory, "options" - end - - def to_h { roles: role_names, diff --git a/lib/kamal/configuration/proxy.rb b/lib/kamal/configuration/proxy.rb index ad8c6e5e..75491089 100644 --- a/lib/kamal/configuration/proxy.rb +++ b/lib/kamal/configuration/proxy.rb @@ -4,6 +4,10 @@ class Kamal::Configuration::Proxy DEFAULT_LOG_REQUEST_HEADERS = [ "Cache-Control", "Last-Modified", "User-Agent" ] CONTAINER_NAME = "kamal-proxy" + MINIMUM_VERSION = "v0.7.0" + HTTP_PORT = 80 + HTTPS_PORT = 443 + delegate :argumentize, :optionize, to: Kamal::Utils attr_reader :config, :proxy_config @@ -26,6 +30,30 @@ def hosts proxy_config["hosts"] || proxy_config["host"]&.split(",") || [] end + def publish_args(http_port, https_port) + argumentize "--publish", [ "#{http_port}:#{HTTP_PORT}", "#{https_port}:#{HTTPS_PORT}" ] + end + + def default_options + publish_args HTTP_PORT, HTTPS_PORT + end + + def image + "basecamp/kamal-proxy:#{MINIMUM_VERSION}" + end + + def container_name + "kamal-proxy" + end + + def directory + File.join config.run_directory, "proxy" + end + + def options_file + File.join directory, "options" + end + def deploy_options { host: hosts, diff --git a/test/cli/proxy_test.rb b/test/cli/proxy_test.rb index 2cfdf0f3..9297d631 100644 --- a/test/cli/proxy_test.rb +++ b/test/cli/proxy_test.rb @@ -4,7 +4,7 @@ class CliProxyTest < CliTestCase test "boot" do run_command("boot").tap do |output| assert_match "docker login", output - assert_match "docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy_image}", output + assert_match "docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy.image}", output end end @@ -18,11 +18,11 @@ class CliProxyTest < CliTestCase exception = assert_raises do run_command("boot").tap do |output| assert_match "docker login", output - assert_match "docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy_image}", output + assert_match "docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy.image}", output 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}" ensure Thread.report_on_exception = false end @@ -31,12 +31,12 @@ class CliProxyTest < CliTestCase Thread.report_on_exception = false SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) .with(:docker, :inspect, "kamal-proxy", "--format '{{.Config.Image}}'", "|", :cut, "-d:", "-f2") - .returns(Kamal::Configuration::PROXY_MINIMUM_VERSION) + .returns(Kamal::Configuration::Proxy::MINIMUM_VERSION) .at_least_once run_command("boot").tap do |output| assert_match "docker login", output - assert_match "docker container start kamal-proxy || docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy_image}", output + assert_match "docker container start kamal-proxy || docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy.image}", output end ensure Thread.report_on_exception = false @@ -57,13 +57,13 @@ class CliProxyTest < CliTestCase assert_match "docker container stop kamal-proxy on 1.1.1.1", output assert_match "Running docker container stop traefik ; docker container prune --force --filter label=org.opencontainers.image.title=Traefik && docker image prune --all --force --filter label=org.opencontainers.image.title=Traefik on 1.1.1.1", output assert_match "docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy on 1.1.1.1", output - assert_match "docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy_image} on 1.1.1.1", output + assert_match "docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy.image} on 1.1.1.1", output assert_match "docker exec kamal-proxy kamal-proxy deploy app-web --target \"abcdefabcdef:80\" --deploy-timeout \"6s\" --drain-timeout \"30s\" --buffer-requests --buffer-responses --log-request-header \"Cache-Control\" --log-request-header \"Last-Modified\" --log-request-header \"User-Agent\" on 1.1.1.1", output assert_match "docker container stop kamal-proxy on 1.1.1.2", output assert_match "Running docker container stop traefik ; docker container prune --force --filter label=org.opencontainers.image.title=Traefik && docker image prune --all --force --filter label=org.opencontainers.image.title=Traefik on 1.1.1.2", output assert_match "docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy on 1.1.1.2", output - assert_match "docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy_image} on 1.1.1.2", output + assert_match "docker run --name kamal-proxy --network kamal --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\") #{KAMAL.config.proxy.image} on 1.1.1.2", output assert_match "docker exec kamal-proxy kamal-proxy deploy app-web --target \"abcdefabcdef:80\" --deploy-timeout \"6s\" --drain-timeout \"30s\" --buffer-requests --buffer-responses --log-request-header \"Cache-Control\" --log-request-header \"Last-Modified\" --log-request-header \"User-Agent\" on 1.1.1.2", output end end @@ -182,7 +182,7 @@ class CliProxyTest < CliTestCase SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) .with(:docker, :inspect, "kamal-proxy", "--format '{{.Config.Image}}'", "|", :cut, "-d:", "-f2") - .returns(Kamal::Configuration::PROXY_MINIMUM_VERSION) + .returns(Kamal::Configuration::Proxy::MINIMUM_VERSION) SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) .with(:docker, :container, :ls, "--all", "--filter", "name=^app-workers-latest$", "--quiet", "|", :xargs, :docker, :inspect, "--format", "'{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}'") @@ -198,7 +198,7 @@ class CliProxyTest < CliTestCase assert_match "/usr/bin/env mkdir -p .kamal", output assert_match "docker network create kamal", output assert_match "docker login -u [REDACTED] -p [REDACTED]", output - assert_match "docker container start kamal-proxy || docker run --name kamal-proxy --network kamal --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}", output + assert_match "docker container start kamal-proxy || docker run --name kamal-proxy --network kamal --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}", output assert_match "/usr/bin/env mkdir -p .kamal", output assert_match %r{docker rename app-web-latest app-web-latest_replaced_.*}, output assert_match "/usr/bin/env mkdir -p .kamal/apps/app/env/roles", output @@ -221,7 +221,7 @@ class CliProxyTest < CliTestCase SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) .with(:docker, :inspect, "kamal-proxy", "--format '{{.Config.Image}}'", "|", :cut, "-d:", "-f2") - .returns(Kamal::Configuration::PROXY_MINIMUM_VERSION) + .returns(Kamal::Configuration::Proxy::MINIMUM_VERSION) SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) .with(:docker, :container, :ls, "--all", "--filter", "name=^app-workers-latest$", "--quiet", "|", :xargs, :docker, :inspect, "--format", "'{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}'") diff --git a/test/commands/proxy_test.rb b/test/commands/proxy_test.rb index 4af78533..2658cf8d 100644 --- a/test/commands/proxy_test.rb +++ b/test/commands/proxy_test.rb @@ -15,7 +15,7 @@ class CommandsProxyTest < ActiveSupport::TestCase test "run" do assert_equal \ - "docker run --name kamal-proxy --network kamal --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}", + "docker run --name kamal-proxy --network kamal --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 @@ -23,7 +23,7 @@ class CommandsProxyTest < ActiveSupport::TestCase @config.delete(:proxy) assert_equal \ - "docker run --name kamal-proxy --network kamal --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}", + "docker run --name kamal-proxy --network kamal --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 diff --git a/test/integration/main_test.rb b/test/integration/main_test.rb index ce32e640..4a8de2be 100644 --- a/test/integration/main_test.rb +++ b/test/integration/main_test.rb @@ -28,7 +28,7 @@ class MainTest < IntegrationTest assert_match /Proxy Host: vm2/, details assert_match /App Host: vm1/, details assert_match /App Host: vm2/, details - assert_match /basecamp\/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION}/, details + assert_match /basecamp\/kamal-proxy:#{Kamal::Configuration::Proxy::MINIMUM_VERSION}/, details assert_match /registry:4443\/app:#{first_version}/, details audit = kamal :audit, capture: true From edf595ac607a1a619bcccb6cb33fb6f35b669607 Mon Sep 17 00:00:00 2001 From: Dmytro Shteflyuk Date: Mon, 30 Sep 2024 17:38:02 -0400 Subject: [PATCH 2/2] Use CONTAINER_NAME constant for kamal-proxy container name --- lib/kamal/configuration/proxy.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kamal/configuration/proxy.rb b/lib/kamal/configuration/proxy.rb index 75491089..64ed057c 100644 --- a/lib/kamal/configuration/proxy.rb +++ b/lib/kamal/configuration/proxy.rb @@ -43,7 +43,7 @@ def image end def container_name - "kamal-proxy" + CONTAINER_NAME end def directory