diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4fa1e801..839bc4e65 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,7 @@ jobs: - "3.1" - "3.2" - "3.3" + - "3.4.0-preview2" gemfile: - Gemfile - gemfiles/rails_edge.gemfile @@ -41,6 +42,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Remove gemfile.lock + run: rm Gemfile.lock + - name: Install Ruby uses: ruby/setup-ruby@v1 with: @@ -49,3 +53,5 @@ jobs: - name: Run tests run: bin/test + env: + RUBYOPT: ${{ startsWith(matrix.ruby-version, '3.4.') && '--enable=frozen-string-literal' || '' }} diff --git a/Dockerfile b/Dockerfile index 3d8af2529..d83468042 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ -# Use the official Ruby 3.2.0 Alpine image as the base image -FROM ruby:3.2.0-alpine +FROM ruby:3.3-alpine # Install docker/buildx-bin COPY --from=docker/buildx-bin /buildx /usr/libexec/docker/cli-plugins/docker-buildx diff --git a/Gemfile.lock b/Gemfile.lock index e055f6a49..093ef9b77 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - kamal (2.1.0) + kamal (2.2.2) activesupport (>= 7.0) base64 (~> 0.2) bcrypt_pbkdf (~> 1.0) diff --git a/lib/kamal/cli/accessory.rb b/lib/kamal/cli/accessory.rb index 14114a25c..6c51c774d 100644 --- a/lib/kamal/cli/accessory.rb +++ b/lib/kamal/cli/accessory.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/array/conversions" + class Kamal::Cli::Accessory < Kamal::Cli::Base desc "boot [NAME]", "Boot new accessory service on host (use NAME=all to boot all accessories)" def boot(name, prepare: true) diff --git a/lib/kamal/cli/main.rb b/lib/kamal/cli/main.rb index 69735f2a3..5fdb5469a 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -135,7 +135,7 @@ def docs(section = nil) puts "No documentation found for #{section}" end - desc "init", "Create config stub in config/deploy.yml and env stub in .env" + desc "init", "Create config stub in config/deploy.yml and secrets stub in .kamal" option :bundle, type: :boolean, default: false, desc: "Add Kamal to the Gemfile and create a bin/kamal binstub" def init require "fileutils" diff --git a/lib/kamal/cli/proxy.rb b/lib/kamal/cli/proxy.rb index 89fb2fd7c..2ce7c2ac5 100644 --- a/lib/kamal/cli/proxy.rb +++ b/lib/kamal/cli/proxy.rb @@ -21,16 +21,18 @@ def boot end end - desc "boot_config ", "Mange kamal-proxy boot configuration" + desc "boot_config ", "Manage 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 :log_max_size, type: :string, default: Kamal::Configuration::PROXY_LOG_MAX_SIZE, desc: "Max size of proxy logs" 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_logging_args(options[:log_max_size])), *options[:docker_options].map { |option| "--#{option}" } ] diff --git a/lib/kamal/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index 7be386b99..fc44b6b93 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -13,12 +13,14 @@ servers: # - 192.168.0.1 # cmd: bin/jobs -# Enable SSL auto certification via Let's Encrypt (and allow for multiple apps on one server). -# Set ssl: false if using something like Cloudflare to terminate SSL (but keep host!). -proxy: +# Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server. +# Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer. +# +# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption. +proxy: ssl: true host: app.example.com - # kamal-proxy connects to your container over port 80, use `app_port` to specify a different port. + # Proxy connects to your container on port 80 by default. # app_port: 3000 # Credentials for your image host. @@ -89,7 +91,7 @@ builder: # directories: # - data:/var/lib/mysql # redis: -# image: redis:7.0 +# image: valkey/valkey:8 # host: 192.168.0.2 # port: 6379 # directories: diff --git a/lib/kamal/cli/templates/sample_hooks/docker-setup.sample b/lib/kamal/cli/templates/sample_hooks/docker-setup.sample index d914913d5..2fb07d7d7 100755 --- a/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +++ b/lib/kamal/cli/templates/sample_hooks/docker-setup.sample @@ -1,13 +1,3 @@ -#!/usr/bin/env ruby +#!/bin/sh -# A sample docker-setup hook -# -# Sets up a Docker network on defined hosts which can then be used by the application’s containers - -hosts = ENV["KAMAL_HOSTS"].split(",") - -hosts.each do |ip| - destination = "root@#{ip}" - puts "Creating a Docker network \"kamal\" on #{destination}" - `ssh #{destination} docker network create kamal` -end +echo "Docker set up on $KAMAL_HOSTS..." diff --git a/lib/kamal/commander/specifics.rb b/lib/kamal/commander/specifics.rb index 190d2b69a..238cc012e 100644 --- a/lib/kamal/commander/specifics.rb +++ b/lib/kamal/commander/specifics.rb @@ -43,7 +43,12 @@ def specified_roles end def specified_hosts - (specific_hosts || config.all_hosts) \ - .select { |host| (specific_roles || config.roles).flat_map(&:hosts).include?(host) } + specified_hosts = specific_hosts || config.all_hosts + + if (specific_role_hosts = specific_roles&.flat_map(&:hosts)).present? + specified_hosts.select { |host| specific_role_hosts.include?(host) } + else + specified_hosts + end end end diff --git a/lib/kamal/commands/base.rb b/lib/kamal/commands/base.rb index 340817441..e71470e42 100644 --- a/lib/kamal/commands/base.rb +++ b/lib/kamal/commands/base.rb @@ -11,14 +11,7 @@ def initialize(config) end def run_over_ssh(*command, host:) - "ssh".tap do |cmd| - if config.ssh.proxy && config.ssh.proxy.is_a?(Net::SSH::Proxy::Jump) - cmd << " -J #{config.ssh.proxy.jump_proxies}" - elsif config.ssh.proxy && config.ssh.proxy.is_a?(Net::SSH::Proxy::Command) - cmd << " -o ProxyCommand='#{config.ssh.proxy.command_line_template}'" - end - cmd << " -t #{config.ssh.user}@#{host} -p #{config.ssh.port} '#{command.join(" ").gsub("'", "'\\\\''")}'" - end + "ssh#{ssh_proxy_args} -t #{config.ssh.user}@#{host} -p #{config.ssh.port} '#{command.join(" ").gsub("'", "'\\\\''")}'" end def container_id_for(container_name:, only_running: false) @@ -96,5 +89,14 @@ def grep(*args) def tags(**details) Kamal::Tags.from_config(config, **details) end + + def ssh_proxy_args + case config.ssh.proxy + when Net::SSH::Proxy::Jump + " -J #{config.ssh.proxy.jump_proxies}" + when Net::SSH::Proxy::Command + " -o ProxyCommand='#{config.ssh.proxy.command_line_template}'" + end + end end end diff --git a/lib/kamal/commands/builder/clone.rb b/lib/kamal/commands/builder/clone.rb index 17d9c931b..a186c7b26 100644 --- a/lib/kamal/commands/builder/clone.rb +++ b/lib/kamal/commands/builder/clone.rb @@ -1,29 +1,31 @@ module Kamal::Commands::Builder::Clone - extend ActiveSupport::Concern - - included do - delegate :clone_directory, :build_directory, to: :"config.builder" - end - def clone - git :clone, Kamal::Git.root, "--recurse-submodules", path: clone_directory + git :clone, escaped_root, "--recurse-submodules", path: config.builder.clone_directory.shellescape end def clone_reset_steps [ - git(:remote, "set-url", :origin, Kamal::Git.root, path: build_directory), - git(:fetch, :origin, path: build_directory), - git(:reset, "--hard", Kamal::Git.revision, path: build_directory), - git(:clean, "-fdx", path: build_directory), - git(:submodule, :update, "--init", path: build_directory) + git(:remote, "set-url", :origin, escaped_root, path: escaped_build_directory), + git(:fetch, :origin, path: escaped_build_directory), + git(:reset, "--hard", Kamal::Git.revision, path: escaped_build_directory), + git(:clean, "-fdx", path: escaped_build_directory), + git(:submodule, :update, "--init", path: escaped_build_directory) ] end def clone_status - git :status, "--porcelain", path: build_directory + git :status, "--porcelain", path: escaped_build_directory end def clone_revision - git :"rev-parse", :HEAD, path: build_directory + git :"rev-parse", :HEAD, path: escaped_build_directory + end + + def escaped_root + Kamal::Git.root.shellescape + end + + def escaped_build_directory + config.builder.build_directory.shellescape end end diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index 6e8799bff..86602fe18 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -14,9 +14,10 @@ class Kamal::Configuration include Validation - PROXY_MINIMUM_VERSION = "v0.7.0" + PROXY_MINIMUM_VERSION = "v0.8.1" PROXY_HTTP_PORT = 80 PROXY_HTTPS_PORT = 443 + PROXY_LOG_MAX_SIZE = "10m" class << self def create_from(config_file:, destination: nil, version: nil) @@ -252,8 +253,12 @@ def proxy_publish_args(http_port, https_port) argumentize "--publish", [ "#{http_port}:#{PROXY_HTTP_PORT}", "#{https_port}:#{PROXY_HTTPS_PORT}" ] end + def proxy_logging_args(max_size) + argumentize "--log-opt", "max-size=#{max_size}" + end + def proxy_options_default - proxy_publish_args PROXY_HTTP_PORT, PROXY_HTTPS_PORT + [ *proxy_publish_args(PROXY_HTTP_PORT, PROXY_HTTPS_PORT), *proxy_logging_args(PROXY_LOG_MAX_SIZE) ] end def proxy_image diff --git a/lib/kamal/configuration/proxy.rb b/lib/kamal/configuration/proxy.rb index 3870a2de9..6232c3e03 100644 --- a/lib/kamal/configuration/proxy.rb +++ b/lib/kamal/configuration/proxy.rb @@ -29,7 +29,7 @@ def hosts def deploy_options { host: hosts, - tls: proxy_config["ssl"], + tls: proxy_config["ssl"].presence, "deploy-timeout": seconds_duration(config.deploy_timeout), "drain-timeout": seconds_duration(config.drain_timeout), "health-check-interval": seconds_duration(proxy_config.dig("healthcheck", "interval")), diff --git a/lib/kamal/version.rb b/lib/kamal/version.rb index b69ff471b..3f5ef1fcb 100644 --- a/lib/kamal/version.rb +++ b/lib/kamal/version.rb @@ -1,3 +1,3 @@ module Kamal - VERSION = "2.1.0" + VERSION = "2.2.2" end diff --git a/test/cli/proxy_test.rb b/test/cli/proxy_test.rb index 8c22c8a2f..c62589fee 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 --log-opt max-size=10m\") #{KAMAL.config.proxy_image}", output end end @@ -18,7 +18,7 @@ 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 --log-opt max-size=10m\") #{KAMAL.config.proxy_image}", output end end @@ -36,7 +36,7 @@ class CliProxyTest < CliTestCase 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 --log-opt max-size=10m\") #{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 --log-opt max-size=10m\") #{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 --log-opt max-size=10m\") #{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 @@ -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 --log-opt max-size=10m\") 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 @@ -240,7 +240,7 @@ class CliProxyTest < CliTestCase run_command("boot_config", "set").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 + assert_match "Uploading \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\" to .kamal/proxy/options on #{host}", output end end end @@ -249,7 +249,16 @@ class CliProxyTest < CliTestCase run_command("boot_config", "set", "--publish", "false").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 \"\" to .kamal/proxy/options on #{host}", output + assert_match "Uploading \"--log-opt max-size=10m\" to .kamal/proxy/options on #{host}", output + end + end + end + + test "boot_config set custom max_size" do + run_command("boot_config", "set", "--log-max-size", "100m").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 --log-opt max-size=100m\" to .kamal/proxy/options on #{host}", output end end end @@ -258,7 +267,7 @@ class CliProxyTest < CliTestCase 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| assert_match "Running /usr/bin/env mkdir -p .kamal/proxy on #{host}", output - assert_match "Uploading \"--publish 8080:80 --publish 8443:443\" to .kamal/proxy/options on #{host}", output + assert_match "Uploading \"--publish 8080:80 --publish 8443:443 --log-opt max-size=10m\" to .kamal/proxy/options on #{host}", output end end end @@ -267,14 +276,14 @@ class CliProxyTest < CliTestCase run_command("boot_config", "set", "--docker_options", "label=foo=bar", "add_host=thishost:thathost").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 --label=foo=bar --add_host=thishost:thathost\" to .kamal/proxy/options on #{host}", output + assert_match "Uploading \"--publish 80:80 --publish 443:443 --log-opt max-size=10m --label=foo=bar --add_host=thishost:thathost\" to .kamal/proxy/options on #{host}", output end end end test "boot_config get" do SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) - .with(:cat, ".kamal/proxy/options", "||", :echo, "\"--publish 80:80 --publish 443:443\"") + .with(:cat, ".kamal/proxy/options", "||", :echo, "\"--publish 80:80 --publish 443:443 --log-opt max-size=10m\"") .returns("--publish 80:80 --publish 8443:443 --label=foo=bar") .twice diff --git a/test/commander_test.rb b/test/commander_test.rb index 54031e803..4f0a829eb 100644 --- a/test/commander_test.rb +++ b/test/commander_test.rb @@ -150,6 +150,27 @@ class CommanderTest < ActiveSupport::TestCase assert_equal [ "1.1.1.2" ], @kamal.proxy_hosts end + test "accessory hosts without filtering" do + configure_with(:deploy_with_single_accessory) + assert_equal [ "1.1.1.5" ], @kamal.accessory_hosts + + configure_with(:deploy_with_accessories_on_independent_server) + assert_equal [ "1.1.1.5", "1.1.1.1", "1.1.1.2" ], @kamal.accessory_hosts + end + + test "accessory hosts with role filtering" do + configure_with(:deploy_with_single_accessory) + @kamal.specific_roles = [ "web" ] + assert_equal [], @kamal.accessory_hosts + + configure_with(:deploy_with_accessories_on_independent_server) + @kamal.specific_roles = [ "web" ] + assert_equal [ "1.1.1.1", "1.1.1.2" ], @kamal.accessory_hosts + + @kamal.specific_roles = [ "workers" ] + assert_equal [], @kamal.accessory_hosts + end + private def configure_with(variant) @kamal = Kamal::Commander.new.tap do |kamal| diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index 182c1bb0b..0e5cad796 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -135,6 +135,14 @@ class CommandsAppTest < ActiveSupport::TestCase new_command.deploy(target: "172.1.0.2").join(" ") end + test "deploy with SSL false" do + @config[:proxy] = { "ssl" => false } + + assert_equal \ + "docker exec kamal-proxy kamal-proxy deploy app-web --target=\"172.1.0.2:80\" --deploy-timeout=\"30s\" --drain-timeout=\"30s\" --buffer-requests --buffer-responses --log-request-header=\"Cache-Control\" --log-request-header=\"Last-Modified\" --log-request-header=\"User-Agent\"", + new_command.deploy(target: "172.1.0.2").join(" ") + end + test "remove" do assert_equal \ "docker exec kamal-proxy kamal-proxy remove app-web", diff --git a/test/commands/builder_test.rb b/test/commands/builder_test.rb index 96e3e75e0..2b9681a1b 100644 --- a/test/commands/builder_test.rb +++ b/test/commands/builder_test.rb @@ -175,15 +175,26 @@ class CommandsBuilderTest < ActiveSupport::TestCase assert_equal "docker info --format '{{index .RegistryConfig.Mirrors 0}}'", command.first_mirror.join(" ") end + test "clone path with spaces" do + command = new_builder_command + Kamal::Git.stubs(:root).returns("/absolute/path with spaces") + clone_command = command.clone.join(" ") + clone_reset_commands = command.clone_reset_steps.map { |a| a.join(" ") } + + assert_match(%r{path\\ with\\ space}, clone_command) + assert_no_match(%r{path with spaces}, clone_command) + + clone_reset_commands.each do |command| + assert_match(%r{path\\ with\\ space}, command) + assert_no_match(%r{path with spaces}, command) + end + end + private def new_builder_command(additional_config = {}) Kamal::Commands::Builder.new(Kamal::Configuration.new(@config.deep_merge(additional_config), version: "123")) end - def build_directory - "#{Dir.tmpdir}/kamal-clones/app/kamal/" - end - def local_arch Kamal::Utils.docker_arch end diff --git a/test/commands/proxy_test.rb b/test/commands/proxy_test.rb index 4af785335..b7cc9f3dc 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 --log-opt max-size=10m\") 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 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION}", new_command.run.join(" ") end @@ -113,7 +113,7 @@ class CommandsProxyTest < ActiveSupport::TestCase test "get_boot_options" do assert_equal \ - "cat .kamal/proxy/options || echo \"--publish 80:80 --publish 443:443\"", + "cat .kamal/proxy/options || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\"", new_command.get_boot_options.join(" ") end diff --git a/test/fixtures/deploy_with_accessories_on_independent_server.yml b/test/fixtures/deploy_with_accessories_on_independent_server.yml new file mode 100644 index 000000000..e6c6825f5 --- /dev/null +++ b/test/fixtures/deploy_with_accessories_on_independent_server.yml @@ -0,0 +1,38 @@ +service: app +image: dhh/app +servers: + web: + - "1.1.1.1" + - "1.1.1.2" + workers: + - "1.1.1.3" + - "1.1.1.4" +registry: + username: user + password: pw +builder: + arch: amd64 + +accessories: + mysql: + image: mysql:5.7 + host: 1.1.1.5 + port: 3306 + env: + clear: + MYSQL_ROOT_HOST: '%' + secret: + - MYSQL_ROOT_PASSWORD + files: + - test/fixtures/files/my.cnf:/etc/mysql/my.cnf + directories: + - data:/var/lib/mysql + redis: + image: redis:latest + roles: + - web + port: 6379 + directories: + - data:/data + +readiness_delay: 0 diff --git a/test/fixtures/deploy_with_single_accessory.yml b/test/fixtures/deploy_with_single_accessory.yml new file mode 100644 index 000000000..4af4a9e6a --- /dev/null +++ b/test/fixtures/deploy_with_single_accessory.yml @@ -0,0 +1,29 @@ +service: app +image: dhh/app +servers: + web: + - "1.1.1.1" + - "1.1.1.2" + workers: + - "1.1.1.3" + - "1.1.1.4" +registry: + username: user + password: pw +builder: + arch: amd64 + +accessories: + mysql: + image: mysql:5.7 + host: 1.1.1.5 + port: 3306 + env: + clear: + MYSQL_ROOT_HOST: '%' + secret: + - MYSQL_ROOT_PASSWORD + files: + - test/fixtures/files/my.cnf:/etc/mysql/my.cnf + directories: + - data:/var/lib/mysql