diff --git a/lib/kamal/cli/app/error_pages.rb b/lib/kamal/cli/app/error_pages.rb index 664f7eff..d15ddf7a 100644 --- a/lib/kamal/cli/app/error_pages.rb +++ b/lib/kamal/cli/app/error_pages.rb @@ -13,7 +13,7 @@ class Kamal::Cli::App::ErrorPages if KAMAL.config.error_pages_path with_error_pages_tmpdir do |local_error_pages_dir| execute *KAMAL.app.create_error_pages_directory - upload! local_error_pages_dir, KAMAL.config.proxy_error_pages_directory, mode: "0700", recursive: true + upload! local_error_pages_dir, KAMAL.config.proxy_boot.error_pages_directory, mode: "0700", recursive: true end end end diff --git a/lib/kamal/cli/proxy.rb b/lib/kamal/cli/proxy.rb index 4baf9419..cd4e45d9 100644 --- a/lib/kamal/cli/proxy.rb +++ b/lib/kamal/cli/proxy.rb @@ -13,8 +13,8 @@ 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, run `kamal proxy reboot` in order to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}" + if version && Kamal::Utils.older_version?(version, Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION) + raise "kamal-proxy version #{version} is too old, run `kamal proxy reboot` in order to update to at least #{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}" end execute *KAMAL.proxy.ensure_apps_config_directory execute *KAMAL.proxy.start_or_run @@ -25,46 +25,48 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base desc "boot_config ", "Manage kamal-proxy boot configuration" option :publish, type: :boolean, default: true, desc: "Publish the proxy ports on the host" option :publish_host_ip, type: :string, repeatable: true, default: nil, desc: "Host IP address to bind HTTP/HTTPS traffic to. Defaults to all interfaces" - 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 :log_max_size, type: :string, default: Kamal::Configuration::PROXY_LOG_MAX_SIZE, desc: "Max size of proxy logs" + option :http_port, type: :numeric, default: Kamal::Configuration::Proxy::Boot::DEFAULT_HTTP_PORT, desc: "HTTP port to publish on the host" + option :https_port, type: :numeric, default: Kamal::Configuration::Proxy::Boot::DEFAULT_HTTPS_PORT, desc: "HTTPS port to publish on the host" + option :log_max_size, type: :string, default: Kamal::Configuration::Proxy::Boot::DEFAULT_LOG_MAX_SIZE, desc: "Max size of proxy logs" option :registry, type: :string, default: nil, desc: "Registry to use for the proxy image" option :repository, type: :string, default: nil, desc: "Repository for the proxy image" option :image_version, type: :string, default: nil, desc: "Version of the proxy to run" option :docker_options, type: :array, default: [], desc: "Docker options to pass to the proxy container", banner: "option=value option2=value2" def boot_config(subcommand) + proxy_boot_config = KAMAL.config.proxy_boot + case subcommand when "set" boot_options = [ - *(KAMAL.config.proxy_publish_args(options[:http_port], options[:https_port], options[:publish_host_ip]) if options[:publish]), - *(KAMAL.config.proxy_logging_args(options[:log_max_size])), + *(proxy_boot_config.publish_args(options[:http_port], options[:https_port], options[:publish_host_ip]) if options[:publish]), + *(proxy_boot_config.logging_args(options[:log_max_size])), *options[:docker_options].map { |option| "--#{option}" } ] image = [ options[:registry].presence, - options[:repository].presence || KAMAL.config.proxy_repository_name, - KAMAL.config.proxy_image_name + options[:repository].presence || proxy_boot_config.repository_name, + proxy_boot_config.image_name ].compact.join("/") image_version = options[:image_version] on(KAMAL.proxy_hosts) do |host| execute(*KAMAL.proxy.ensure_proxy_directory) - if boot_options != KAMAL.config.proxy_default_boot_options - upload! StringIO.new(boot_options.join(" ")), KAMAL.config.proxy_options_file + if boot_options != proxy_boot_config.default_boot_options + upload! StringIO.new(boot_options.join(" ")), proxy_boot_config.options_file else execute *KAMAL.proxy.reset_boot_options, raise_on_non_zero_exit: false end - if image != KAMAL.config.proxy_image_default - upload! StringIO.new(image), KAMAL.config.proxy_image_file + if image != proxy_boot_config.image_default + upload! StringIO.new(image), proxy_boot_config.image_file else execute *KAMAL.proxy.reset_image, raise_on_non_zero_exit: false end if image_version - upload! StringIO.new(image_version), KAMAL.config.proxy_image_version_file + upload! StringIO.new(image_version), proxy_boot_config.image_version_file else execute *KAMAL.proxy.reset_image_version, raise_on_non_zero_exit: false end diff --git a/lib/kamal/commands/accessory.rb b/lib/kamal/commands/accessory.rb index 60279dfc..4a76d6f6 100644 --- a/lib/kamal/commands/accessory.rb +++ b/lib/kamal/commands/accessory.rb @@ -6,7 +6,6 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base :network_args, :publish_args, :env_args, :volume_args, :label_args, :option_args, :secrets_io, :secrets_path, :env_directory, :proxy, :running_proxy?, :registry, to: :accessory_config - delegate :proxy_container_name, to: :config def initialize(config, name:) super(config) diff --git a/lib/kamal/commands/accessory/proxy.rb b/lib/kamal/commands/accessory/proxy.rb index 195a321b..833088da 100644 --- a/lib/kamal/commands/accessory/proxy.rb +++ b/lib/kamal/commands/accessory/proxy.rb @@ -1,5 +1,5 @@ module Kamal::Commands::Accessory::Proxy - delegate :proxy_container_name, to: :config + delegate :container_name, to: :"config.proxy_boot", prefix: :proxy def deploy(target:) proxy_exec :deploy, service_name, *proxy.deploy_command_args(target: target) diff --git a/lib/kamal/commands/app/error_pages.rb b/lib/kamal/commands/app/error_pages.rb index d51dba3f..3a21bdaf 100644 --- a/lib/kamal/commands/app/error_pages.rb +++ b/lib/kamal/commands/app/error_pages.rb @@ -1,9 +1,9 @@ module Kamal::Commands::App::ErrorPages def create_error_pages_directory - make_directory(config.proxy_error_pages_directory) + make_directory(config.proxy_boot.error_pages_directory) end def clean_up_error_pages - [ :find, config.proxy_error_pages_directory, "-mindepth", "1", "-maxdepth", "1", "!", "-name", KAMAL.config.version, "-exec", "rm", "-rf", "{} +" ] + [ :find, config.proxy_boot.error_pages_directory, "-mindepth", "1", "-maxdepth", "1", "!", "-name", KAMAL.config.version, "-exec", "rm", "-rf", "{} +" ] end end diff --git a/lib/kamal/commands/app/proxy.rb b/lib/kamal/commands/app/proxy.rb index 56d0ccea..6d015a0b 100644 --- a/lib/kamal/commands/app/proxy.rb +++ b/lib/kamal/commands/app/proxy.rb @@ -1,5 +1,5 @@ module Kamal::Commands::App::Proxy - delegate :proxy_container_name, to: :config + delegate :container_name, to: :"config.proxy_boot", prefix: :proxy def deploy(target:) proxy_exec :deploy, role.container_prefix, *role.proxy.deploy_command_args(target: target) @@ -18,7 +18,7 @@ module Kamal::Commands::App::Proxy end def remove_proxy_app_directory - remove_directory config.proxy_app_directory + remove_directory config.proxy_boot.app_directory end private diff --git a/lib/kamal/commands/proxy.rb b/lib/kamal/commands/proxy.rb index d3eb6c31..2193fff7 100644 --- a/lib/kamal/commands/proxy.rb +++ b/lib/kamal/commands/proxy.rb @@ -58,15 +58,15 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base end def ensure_proxy_directory - make_directory config.proxy_directory + make_directory config.proxy_boot.host_directory end def remove_proxy_directory - remove_directory config.proxy_directory + remove_directory config.proxy_boot.host_directory end def ensure_apps_config_directory - make_directory config.proxy_apps_directory + make_directory config.proxy_boot.apps_directory end def boot_config @@ -74,32 +74,32 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base end def read_boot_options - read_file(config.proxy_options_file, default: config.proxy_options_default.join(" ")) + read_file(config.proxy_boot.options_file, default: config.proxy_boot.default_boot_options.join(" ")) end def read_image - read_file(config.proxy_image_file, default: config.proxy_image_default) + read_file(config.proxy_boot.image_file, default: config.proxy_boot.image_default) end def read_image_version - read_file(config.proxy_image_version_file, default: Kamal::Configuration::PROXY_MINIMUM_VERSION) + read_file(config.proxy_boot.image_version_file, default: Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION) end def reset_boot_options - remove_file config.proxy_options_file + remove_file config.proxy_boot.options_file end def reset_image - remove_file config.proxy_image_file + remove_file config.proxy_boot.image_file end def reset_image_version - remove_file config.proxy_image_version_file + remove_file config.proxy_boot.image_version_file end private def container_name - config.proxy_container_name + config.proxy_boot.container_name end def read_file(file, default: nil) @@ -114,6 +114,6 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base "--detach", "--restart", "unless-stopped", "--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", - *config.proxy_apps_volume.docker_args + *config.proxy_boot.apps_volume.docker_args end end diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index 326e1f71..26450170 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -10,15 +10,10 @@ class Kamal::Configuration delegate :argumentize, :optionize, to: Kamal::Utils attr_reader :destination, :raw_config, :secrets - attr_reader :accessories, :aliases, :boot, :builder, :env, :logging, :proxy, :servers, :ssh, :sshkit, :registry + attr_reader :accessories, :aliases, :boot, :builder, :env, :logging, :proxy, :proxy_boot, :servers, :ssh, :sshkit, :registry include Validation - PROXY_MINIMUM_VERSION = "v0.8.7" - PROXY_HTTP_PORT = 80 - PROXY_HTTPS_PORT = 443 - PROXY_LOG_MAX_SIZE = "10m" - class << self def create_from(config_file:, destination: nil, version: nil) ENV["KAMAL_DESTINATION"] = destination @@ -69,6 +64,7 @@ class Kamal::Configuration @logging = Logging.new(logging_config: @raw_config.logging) @proxy = Proxy.new(config: self, proxy_config: @raw_config.key?(:proxy) ? @raw_config.proxy : {}) + @proxy_boot = Proxy::Boot.new(config: self) @ssh = Ssh.new(config: self) @sshkit = Sshkit.new(config: self) @@ -257,95 +253,6 @@ class Kamal::Configuration env_tags.detect { |t| t.name == name.to_s } end - def proxy_publish_args(http_port, https_port, bind_ips = nil) - ensure_valid_bind_ips(bind_ips) - - (bind_ips || [ nil ]).map do |bind_ip| - bind_ip = format_bind_ip(bind_ip) - publish_http = [ bind_ip, http_port, PROXY_HTTP_PORT ].compact.join(":") - publish_https = [ bind_ip, https_port, PROXY_HTTPS_PORT ].compact.join(":") - - argumentize "--publish", [ publish_http, publish_https ] - end.join(" ") - end - - def proxy_logging_args(max_size) - argumentize "--log-opt", "max-size=#{max_size}" if max_size.present? - end - - def proxy_default_boot_options - [ - *(KAMAL.config.proxy_publish_args(Kamal::Configuration::PROXY_HTTP_PORT, Kamal::Configuration::PROXY_HTTPS_PORT, nil)), - *(KAMAL.config.proxy_logging_args(Kamal::Configuration::PROXY_LOG_MAX_SIZE)) - ] - end - - def proxy_options_default - [ *proxy_publish_args(PROXY_HTTP_PORT, PROXY_HTTPS_PORT), *proxy_logging_args(PROXY_LOG_MAX_SIZE) ] - end - - def proxy_repository_name - "basecamp" - end - - def proxy_image_name - "kamal-proxy" - end - - def proxy_image_default - "#{proxy_repository_name}/#{proxy_image_name}" - 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 proxy_image_file - File.join proxy_directory, "image" - end - - def proxy_image_version_file - File.join proxy_directory, "image_version" - end - - def proxy_apps_directory - File.join proxy_directory, "apps-config" - end - - def proxy_apps_container_directory - "/home/kamal-proxy/.apps-config" - end - - def proxy_apps_volume - Volume.new \ - host_path: proxy_apps_directory, - container_path: proxy_apps_container_directory - end - - def proxy_app_directory - File.join proxy_apps_directory, service_and_destination - end - - def proxy_app_container_directory - File.join proxy_apps_container_directory, service_and_destination - end - - def proxy_error_pages_directory - File.join proxy_app_directory, "error_pages" - end - - def proxy_error_pages_container_directory - File.join proxy_app_container_directory, "error_pages" - end - def to_h { roles: role_names, @@ -416,15 +323,6 @@ class Kamal::Configuration true end - def ensure_valid_bind_ips(bind_ips) - bind_ips.present? && bind_ips.each do |ip| - next if ip =~ Resolv::IPv4::Regex || ip =~ Resolv::IPv6::Regex - raise ArgumentError, "Invalid publish IP address: #{ip}" - end - - true - end - def ensure_retain_containers_valid raise Kamal::ConfigurationError, "Must retain at least 1 container" if retain_containers < 1 @@ -456,15 +354,6 @@ class Kamal::Configuration true end - def format_bind_ip(ip) - # Ensure IPv6 address inside square brackets - e.g. [::1] - if ip =~ Resolv::IPv6::Regex && ip !~ /\[.*\]/ - "[#{ip}]" - else - ip - end - end - def role_names raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort end diff --git a/lib/kamal/configuration/proxy.rb b/lib/kamal/configuration/proxy.rb index 19bc25f7..b5afbaae 100644 --- a/lib/kamal/configuration/proxy.rb +++ b/lib/kamal/configuration/proxy.rb @@ -74,6 +74,6 @@ class Kamal::Configuration::Proxy end def error_pages - File.join config.proxy_error_pages_container_directory, config.version if config.error_pages_path + File.join config.proxy_boot.error_pages_container_directory, config.version if config.error_pages_path end end diff --git a/lib/kamal/configuration/proxy/boot.rb b/lib/kamal/configuration/proxy/boot.rb new file mode 100644 index 00000000..19adfa91 --- /dev/null +++ b/lib/kamal/configuration/proxy/boot.rb @@ -0,0 +1,117 @@ +class Kamal::Configuration::Proxy::Boot + MINIMUM_VERSION = "v0.8.7" + DEFAULT_HTTP_PORT = 80 + DEFAULT_HTTPS_PORT = 443 + DEFAULT_LOG_MAX_SIZE = "10m" + + attr_reader :config + delegate :argumentize, :optionize, to: Kamal::Utils + + def initialize(config:) + @config = config + end + + def publish_args(http_port, https_port, bind_ips = nil) + ensure_valid_bind_ips(bind_ips) + + (bind_ips || [ nil ]).map do |bind_ip| + bind_ip = format_bind_ip(bind_ip) + publish_http = [ bind_ip, http_port, DEFAULT_HTTP_PORT ].compact.join(":") + publish_https = [ bind_ip, https_port, DEFAULT_HTTPS_PORT ].compact.join(":") + + argumentize "--publish", [ publish_http, publish_https ] + end.join(" ") + end + + def logging_args(max_size) + argumentize "--log-opt", "max-size=#{max_size}" if max_size.present? + end + + def default_boot_options + [ + *(publish_args(DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT, nil)), + *(logging_args(DEFAULT_LOG_MAX_SIZE)) + ] + end + + def repository_name + "basecamp" + end + + def image_name + "kamal-proxy" + end + + def image_default + "#{repository_name}/#{image_name}" + end + + def container_name + "kamal-proxy" + end + + def host_directory + File.join config.run_directory, "proxy" + end + + def options_file + File.join host_directory, "options" + end + + def image_file + File.join host_directory, "image" + end + + def image_version_file + File.join host_directory, "image_version" + end + + def apps_directory + File.join host_directory, "apps-config" + end + + def apps_container_directory + "/home/kamal-proxy/.apps-config" + end + + def apps_volume + Kamal::Configuration::Volume.new \ + host_path: apps_directory, + container_path: apps_container_directory + end + + def app_directory + File.join apps_directory, config.service_and_destination + end + + def app_container_directory + File.join apps_container_directory, config.service_and_destination + end + + def error_pages_directory + File.join app_directory, "error_pages" + end + + def error_pages_container_directory + File.join app_container_directory, "error_pages" + end + + private + def ensure_valid_bind_ips(bind_ips) + bind_ips.present? && bind_ips.each do |ip| + next if ip =~ Resolv::IPv4::Regex || ip =~ Resolv::IPv6::Regex + raise ArgumentError, "Invalid publish IP address: #{ip}" + end + + true + end + + def format_bind_ip(ip) + # Ensure IPv6 address inside square brackets - e.g. [::1] + if ip =~ Resolv::IPv6::Regex && ip !~ /\[.*\]/ + "[#{ip}]" + else + ip + end + end +end diff --git a/test/cli/proxy_test.rb b/test/cli/proxy_test.rb index 604676fe..428fc515 100644 --- a/test/cli/proxy_test.rb +++ b/test/cli/proxy_test.rb @@ -5,7 +5,7 @@ class CliProxyTest < CliTestCase run_command("boot").tap do |output| assert_match "docker login", output assert_match "mkdir -p .kamal/proxy/apps-config", output - assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::PROXY_MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output + assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output end end @@ -19,11 +19,11 @@ class CliProxyTest < CliTestCase exception = assert_raises do run_command("boot").tap do |output| assert_match "docker login", output - assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::PROXY_MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output + assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output end end - 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}" + 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::Boot::MINIMUM_VERSION}" ensure Thread.report_on_exception = false end @@ -32,12 +32,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}}'", "|", :awk, "-F:", "'{print $NF}'") - .returns(Kamal::Configuration::PROXY_MINIMUM_VERSION) + .returns(Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION) .at_least_once run_command("boot").tap do |output| assert_match "docker login", output - assert_match "docker container start kamal-proxy || echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::PROXY_MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output + assert_match "docker container start kamal-proxy || echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output end ensure Thread.report_on_exception = false @@ -58,13 +58,13 @@ class CliProxyTest < CliTestCase assert_match "docker container stop kamal-proxy 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 "mkdir -p .kamal/proxy/apps-config on 1.1.1.1", output - assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::PROXY_MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config on 1.1.1.1", output + assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config 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 "docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy on 1.1.1.2", output assert_match "mkdir -p .kamal/proxy/apps-config on 1.1.1.1", output - assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::PROXY_MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config on 1.1.1.2", output + assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config 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 @@ -183,7 +183,7 @@ class CliProxyTest < CliTestCase SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) .with(:docker, :inspect, "kamal-proxy", "--format '{{.Config.Image}}'", "|", :awk, "-F:", "'{print $NF}'") - .returns(Kamal::Configuration::PROXY_MINIMUM_VERSION) + .returns(Kamal::Configuration::Proxy::Boot::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}}'") @@ -199,7 +199,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 || echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::PROXY_MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output + assert_match "docker container start kamal-proxy || echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", 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 @@ -222,7 +222,7 @@ class CliProxyTest < CliTestCase SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) .with(:docker, :inspect, "kamal-proxy", "--format '{{.Config.Image}}'", "|", :awk, "-F:", "'{print $NF}'") - .returns(Kamal::Configuration::PROXY_MINIMUM_VERSION) + .returns(Kamal::Configuration::Proxy::Boot::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 94fe9c66..e141725a 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 \ - "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::PROXY_MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config", + "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config", new_command.run.join(" ") end @@ -23,7 +23,7 @@ class CommandsProxyTest < ActiveSupport::TestCase @config.delete(:proxy) assert_equal \ - "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::PROXY_MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config", + "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config", new_command.run.join(" ") end @@ -125,7 +125,7 @@ class CommandsProxyTest < ActiveSupport::TestCase test "read_image_version" do assert_equal \ - "cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::PROXY_MINIMUM_VERSION}\"", + "cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\"", new_command.read_image_version.join(" ") end diff --git a/test/configuration/proxy/boot_test.rb b/test/configuration/proxy/boot_test.rb new file mode 100644 index 00000000..90dee1b7 --- /dev/null +++ b/test/configuration/proxy/boot_test.rb @@ -0,0 +1,29 @@ +require "test_helper" + +class ConfigurationProxyBootTest < ActiveSupport::TestCase + setup do + ENV["RAILS_MASTER_KEY"] = "456" + ENV["VERSION"] = "missing" + + @deploy = { + service: "app", image: "dhh/app", + registry: { "username" => "dhh", "password" => "secret" }, + builder: { "arch" => "amd64" }, + env: { "REDIS_URL" => "redis://x/y" }, + servers: [ "1.1.1.1", "1.1.1.2" ], + volumes: [ "/local/path:/container/path" ] + } + + @config = Kamal::Configuration.new(@deploy) + @proxy_boot_config = @config.proxy_boot + end + + test "proxy directories" do + assert_equal ".kamal/proxy/apps-config", @proxy_boot_config.apps_directory + assert_equal "/home/kamal-proxy/.apps-config", @proxy_boot_config.apps_container_directory + assert_equal ".kamal/proxy/apps-config/app", @proxy_boot_config.app_directory + assert_equal "/home/kamal-proxy/.apps-config/app", @proxy_boot_config.app_container_directory + assert_equal ".kamal/proxy/apps-config/app/error_pages", @proxy_boot_config.error_pages_directory + assert_equal "/home/kamal-proxy/.apps-config/app/error_pages", @proxy_boot_config.error_pages_container_directory + end +end diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 571ed0a7..73756c88 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -410,13 +410,4 @@ class ConfigurationTest < ActiveSupport::TestCase assert_equal "Different roles can't share the same host for SSL: foo.example.com", exception.message end - - test "proxy directories" do - assert_equal ".kamal/proxy/apps-config", @config.proxy_apps_directory - assert_equal "/home/kamal-proxy/.apps-config", @config.proxy_apps_container_directory - assert_equal ".kamal/proxy/apps-config/app", @config.proxy_app_directory - assert_equal "/home/kamal-proxy/.apps-config/app", @config.proxy_app_container_directory - assert_equal ".kamal/proxy/apps-config/app/error_pages", @config.proxy_error_pages_directory - assert_equal "/home/kamal-proxy/.apps-config/app/error_pages", @config.proxy_error_pages_container_directory - end end diff --git a/test/integration/main_test.rb b/test/integration/main_test.rb index 3b56fbb3..604bd78c 100644 --- a/test/integration/main_test.rb +++ b/test/integration/main_test.rb @@ -32,7 +32,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::Boot::MINIMUM_VERSION}/, details assert_match /registry:4443\/app:#{first_version}/, details audit = kamal :audit, capture: true