diff --git a/lib/kamal/cli/accessory.rb b/lib/kamal/cli/accessory.rb index 47bc1a06..b9cfee1f 100644 --- a/lib/kamal/cli/accessory.rb +++ b/lib/kamal/cli/accessory.rb @@ -5,11 +5,11 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base if name == "all" KAMAL.accessory_names.each { |accessory_name| boot(accessory_name) } else - with_accessory(name) do |accessory| + with_accessory(name) do |accessory, hosts| directories(name) upload(name) - on(accessory.hosts) do + on(hosts) do execute *KAMAL.registry.login if login execute *KAMAL.auditor.record("Booted #{name} accessory"), verbosity: :debug execute *accessory.run @@ -22,8 +22,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base desc "upload [NAME]", "Upload accessory files to host", hide: true def upload(name) mutating do - with_accessory(name) do |accessory| - on(accessory.hosts) do + with_accessory(name) do |accessory, hosts| + on(hosts) do accessory.files.each do |(local, remote)| accessory.ensure_local_file_present(local) @@ -39,8 +39,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base desc "directories [NAME]", "Create accessory directories on host", hide: true def directories(name) mutating do - with_accessory(name) do |accessory| - on(accessory.hosts) do + with_accessory(name) do |accessory, hosts| + on(hosts) do accessory.directories.keys.each do |host_path| execute *accessory.make_directory(host_path) end @@ -55,8 +55,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base if name == "all" KAMAL.accessory_names.each { |accessory_name| reboot(accessory_name) } else - with_accessory(name) do |accessory| - on(accessory.hosts) do + with_accessory(name) do |accessory, hosts| + on(hosts) do execute *KAMAL.registry.login end @@ -71,8 +71,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base desc "start [NAME]", "Start existing accessory container on host" def start(name) mutating do - with_accessory(name) do |accessory| - on(accessory.hosts) do + with_accessory(name) do |accessory, hosts| + on(hosts) do execute *KAMAL.auditor.record("Started #{name} accessory"), verbosity: :debug execute *accessory.start end @@ -83,8 +83,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base desc "stop [NAME]", "Stop existing accessory container on host" def stop(name) mutating do - with_accessory(name) do |accessory| - on(accessory.hosts) do + with_accessory(name) do |accessory, hosts| + on(hosts) do execute *KAMAL.auditor.record("Stopped #{name} accessory"), verbosity: :debug execute *accessory.stop, raise_on_non_zero_exit: false end @@ -107,8 +107,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base if name == "all" KAMAL.accessory_names.each { |accessory_name| details(accessory_name) } else - with_accessory(name) do |accessory| - on(accessory.hosts) { puts capture_with_info(*accessory.info) } + with_accessory(name) do |accessory, hosts| + on(hosts) { puts capture_with_info(*accessory.info) } end end end @@ -117,7 +117,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base option :interactive, aliases: "-i", type: :boolean, default: false, desc: "Execute command over ssh for an interactive shell (use for console/bash)" option :reuse, type: :boolean, default: false, desc: "Reuse currently running container instead of starting a new one" def exec(name, cmd) - with_accessory(name) do |accessory| + with_accessory(name) do |accessory, hosts| case when options[:interactive] && options[:reuse] say "Launching interactive command with via SSH from existing container...", :magenta @@ -129,14 +129,14 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base when options[:reuse] say "Launching command from existing container...", :magenta - on(accessory.hosts) do + on(hosts) do execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on #{name} accessory"), verbosity: :debug capture_with_info(*accessory.execute_in_existing_container(cmd)) end else say "Launching command from new container...", :magenta - on(accessory.hosts) do + on(hosts) do execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on #{name} accessory"), verbosity: :debug capture_with_info(*accessory.execute_in_new_container(cmd)) end @@ -150,12 +150,12 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)" option :follow, aliases: "-f", desc: "Follow logs on primary server (or specific host set by --hosts)" def logs(name) - with_accessory(name) do |accessory| + with_accessory(name) do |accessory, hosts| grep = options[:grep] if options[:follow] run_locally do - info "Following logs on #{accessory.hosts}..." + info "Following logs on #{hosts}..." info accessory.follow_logs(grep: grep) exec accessory.follow_logs(grep: grep) end @@ -163,7 +163,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base since = options[:since] lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set - on(accessory.hosts) do + on(hosts) do puts capture_with_info(*accessory.logs(since: since, lines: lines, grep: grep)) end end @@ -192,8 +192,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base desc "remove_container [NAME]", "Remove accessory container from host", hide: true def remove_container(name) mutating do - with_accessory(name) do |accessory| - on(accessory.hosts) do + with_accessory(name) do |accessory, hosts| + on(hosts) do execute *KAMAL.auditor.record("Remove #{name} accessory container"), verbosity: :debug execute *accessory.remove_container end @@ -204,8 +204,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base desc "remove_image [NAME]", "Remove accessory image from host", hide: true def remove_image(name) mutating do - with_accessory(name) do |accessory| - on(accessory.hosts) do + with_accessory(name) do |accessory, hosts| + on(hosts) do execute *KAMAL.auditor.record("Removed #{name} accessory image"), verbosity: :debug execute *accessory.remove_image end @@ -216,8 +216,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base desc "remove_service_directory [NAME]", "Remove accessory directory used for uploaded files and data directories from host", hide: true def remove_service_directory(name) mutating do - with_accessory(name) do |accessory| - on(accessory.hosts) do + with_accessory(name) do |accessory, hosts| + on(hosts) do execute *accessory.remove_service_directory end end @@ -227,7 +227,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base private def with_accessory(name) if accessory = KAMAL.accessory(name) - yield accessory + yield accessory, accessory_hosts(accessory) else error_on_missing_accessory(name) end @@ -240,4 +240,12 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base "No accessory by the name of '#{name}'" + (options ? " (options: #{options.to_sentence})" : "") end + + def accessory_hosts(accessory) + if KAMAL.specific_hosts&.any? + KAMAL.specific_hosts & accessory.hosts + else + accessory.hosts + end + end end diff --git a/lib/kamal/cli/prune.rb b/lib/kamal/cli/prune.rb index 236c7d55..498e4ec4 100644 --- a/lib/kamal/cli/prune.rb +++ b/lib/kamal/cli/prune.rb @@ -18,12 +18,16 @@ class Kamal::Cli::Prune < Kamal::Cli::Base end end - desc "containers", "Prune all stopped containers, except the last 5" + desc "containers", "Prune all stopped containers, except the last n (default 5)" + option :retain, type: :numeric, default: nil, desc: "Number of containers to retain" def containers + retain = options.fetch(:retain, KAMAL.config.retain_containers) + raise "retain must be at least 1" if retain < 1 + mutating do on(KAMAL.hosts) do execute *KAMAL.auditor.record("Pruned containers"), verbosity: :debug - execute *KAMAL.prune.app_containers + execute *KAMAL.prune.app_containers(retain: retain) execute *KAMAL.prune.healthcheck_containers end end diff --git a/lib/kamal/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index 20bbe71a..af018554 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -77,6 +77,10 @@ registry: # Bridge fingerprinted assets, like JS and CSS, between versions to avoid # hitting 404 on in-flight requests. Combines all files from new and old # version inside the asset_path. +# +# If your app is using the Sprockets gem, ensure it sets `config.assets.manifest`. +# See https://github.com/basecamp/kamal/issues/626 for details +# # asset_path: /rails/public/assets # Configure rolling deploys by setting a wait time between batches of restarts. diff --git a/lib/kamal/commands/builder/base.rb b/lib/kamal/commands/builder/base.rb index 8723fa45..f710807c 100644 --- a/lib/kamal/commands/builder/base.rb +++ b/lib/kamal/commands/builder/base.rb @@ -3,7 +3,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base class BuilderError < StandardError; end delegate :argumentize, to: Kamal::Utils - delegate :args, :secrets, :dockerfile, :local_arch, :local_host, :remote_arch, :remote_host, :cache_from, :cache_to, to: :builder_config + delegate :args, :secrets, :dockerfile, :local_arch, :local_host, :remote_arch, :remote_host, :cache_from, :cache_to, :ssh, to: :builder_config def clean docker :image, :rm, "--force", config.absolute_image @@ -14,7 +14,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_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_ssh ] end def build_context @@ -60,6 +60,10 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base end end + def build_ssh + argumentize "--ssh", ssh if ssh.present? + end + def builder_config config.builder end diff --git a/lib/kamal/commands/prune.rb b/lib/kamal/commands/prune.rb index f9f37b24..40f7dfc4 100644 --- a/lib/kamal/commands/prune.rb +++ b/lib/kamal/commands/prune.rb @@ -13,10 +13,10 @@ class Kamal::Commands::Prune < Kamal::Commands::Base "while read image tag; do docker rmi $tag; done" end - def app_containers(keep_last: 5) + def app_containers(retain:) pipe \ docker(:ps, "-q", "-a", *service_filter, *stopped_containers_filters), - "tail -n +#{keep_last + 1}", + "tail -n +#{retain + 1}", "while read container_id; do docker rm $container_id; done" end diff --git a/lib/kamal/commands/traefik.rb b/lib/kamal/commands/traefik.rb index c6ec8c8d..bb8f048b 100644 --- a/lib/kamal/commands/traefik.rb +++ b/lib/kamal/commands/traefik.rb @@ -1,7 +1,7 @@ class Kamal::Commands::Traefik < Kamal::Commands::Base delegate :argumentize, :optionize, to: Kamal::Utils - DEFAULT_IMAGE = "traefik:v2.9" + DEFAULT_IMAGE = "traefik:v2.10" CONTAINER_PORT = 80 DEFAULT_ARGS = { 'log.level' => 'DEBUG' diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index 3fb87124..04c870a8 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -127,6 +127,10 @@ class Kamal::Configuration raw_config.require_destination end + def retain_containers + raw_config.retain_containers || 5 + end + def volume_args if raw_config.volumes.present? @@ -218,7 +222,7 @@ class Kamal::Configuration def valid? - ensure_destination_if_required && ensure_required_keys_present && ensure_valid_kamal_version && ensure_valid_service_name + ensure_destination_if_required && ensure_required_keys_present && ensure_valid_kamal_version && ensure_retain_containers_valid && ensure_valid_service_name end def to_h @@ -297,6 +301,12 @@ class Kamal::Configuration true end + def ensure_retain_containers_valid + raise ArgumentError, "Must retain at least 1 container" if retain_containers < 1 + + true + end + def role_names raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort diff --git a/lib/kamal/configuration/accessory.rb b/lib/kamal/configuration/accessory.rb index 8fdcd227..d26c6c85 100644 --- a/lib/kamal/configuration/accessory.rb +++ b/lib/kamal/configuration/accessory.rb @@ -8,7 +8,7 @@ class Kamal::Configuration::Accessory end def service_name - "#{config.service}-#{name}" + specifics["service"] || "#{config.service}-#{name}" end def image diff --git a/lib/kamal/configuration/builder.rb b/lib/kamal/configuration/builder.rb index c7d81922..9daa3138 100644 --- a/lib/kamal/configuration/builder.rb +++ b/lib/kamal/configuration/builder.rb @@ -81,6 +81,10 @@ class Kamal::Configuration::Builder end end + def ssh + @options["ssh"] + end + private def valid? if @options["cache"] && @options["cache"]["type"] diff --git a/lib/kamal/sshkit_with_ext.rb b/lib/kamal/sshkit_with_ext.rb index eb8f359b..e0c62c3a 100644 --- a/lib/kamal/sshkit_with_ext.rb +++ b/lib/kamal/sshkit_with_ext.rb @@ -1,5 +1,6 @@ require "sshkit" require "sshkit/dsl" +require "net/scp" require "active_support/core_ext/hash/deep_merge" require "json" diff --git a/test/cli/accessory_test.rb b/test/cli/accessory_test.rb index c4cf4828..d8f3fc63 100644 --- a/test/cli/accessory_test.rb +++ b/test/cli/accessory_test.rb @@ -148,6 +148,30 @@ class CliAccessoryTest < CliTestCase assert_match "rm -rf app-mysql", run_command("remove_service_directory", "mysql") end + test "hosts param respected" do + Kamal::Cli::Accessory.any_instance.expects(:directories).with("redis") + Kamal::Cli::Accessory.any_instance.expects(:upload).with("redis") + + run_command("boot", "redis", "--hosts", "1.1.1.1").tap do |output| + assert_match /docker login.*on 1.1.1.1/, output + refute_match /docker login.*on 1.1.1.2/, output + assert_match "docker run --name app-redis --detach --restart unless-stopped --log-opt max-size=\"10m\" --publish 6379:6379 --env-file .kamal/env/accessories/app-redis.env --volume $PWD/app-redis/data:/data --label service=\"app-redis\" redis:latest on 1.1.1.1", output + refute_match "docker run --name app-redis --detach --restart unless-stopped --log-opt max-size=\"10m\" --publish 6379:6379 --env-file .kamal/env/accessories/app-redis.env --volume $PWD/app-redis/data:/data --label service=\"app-redis\" redis:latest on 1.1.1.2", output + end + end + + test "hosts param intersected with configuration" do + Kamal::Cli::Accessory.any_instance.expects(:directories).with("redis") + Kamal::Cli::Accessory.any_instance.expects(:upload).with("redis") + + run_command("boot", "redis", "--hosts", "1.1.1.1,1.1.1.3").tap do |output| + assert_match /docker login.*on 1.1.1.1/, output + refute_match /docker login.*on 1.1.1.3/, output + assert_match "docker run --name app-redis --detach --restart unless-stopped --log-opt max-size=\"10m\" --publish 6379:6379 --env-file .kamal/env/accessories/app-redis.env --volume $PWD/app-redis/data:/data --label service=\"app-redis\" redis:latest on 1.1.1.1", output + refute_match "docker run --name app-redis --detach --restart unless-stopped --log-opt max-size=\"10m\" --publish 6379:6379 --env-file .kamal/env/accessories/app-redis.env --volume $PWD/app-redis/data:/data --label service=\"app-redis\" redis:latest on 1.1.1.3", output + end + end + private def run_command(*command) stdouted { Kamal::Cli::Accessory.start([*command, "-c", "test/fixtures/deploy_with_accessories.yml"]) } diff --git a/test/cli/prune_test.rb b/test/cli/prune_test.rb index 77c3ebd4..11acc469 100644 --- a/test/cli/prune_test.rb +++ b/test/cli/prune_test.rb @@ -20,6 +20,15 @@ class CliPruneTest < CliTestCase assert_match /docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +6 | while read container_id; do docker rm $container_id; done on 1.1.1.\d/, output assert_match /docker container prune --force --filter label=service=healthcheck-app on 1.1.1.\d/, output end + + run_command("containers", "--retain", "10").tap do |output| + assert_match /docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +11 | while read container_id; do docker rm $container_id; done on 1.1.1.\d/, output + assert_match /docker container prune --force --filter label=service=healthcheck-app on 1.1.1.\d/, output + end + + assert_raises(RuntimeError, "retain must be at least 1") do + run_command("containers", "--retain", "0") + end end private diff --git a/test/commands/accessory_test.rb b/test/commands/accessory_test.rb index 687c7fe5..92ed1211 100644 --- a/test/commands/accessory_test.rb +++ b/test/commands/accessory_test.rb @@ -34,6 +34,7 @@ class CommandsAccessoryTest < ActiveSupport::TestCase ] }, "busybox" => { + "service" => "custom-busybox", "image" => "busybox:latest", "host" => "1.1.1.7" } @@ -57,7 +58,7 @@ class CommandsAccessoryTest < ActiveSupport::TestCase new_command(:redis).run.join(" ") assert_equal \ - "docker run --name app-busybox --detach --restart unless-stopped --log-opt max-size=\"10m\" --env-file .kamal/env/accessories/app-busybox.env --label service=\"app-busybox\" busybox:latest", + "docker run --name custom-busybox --detach --restart unless-stopped --log-opt max-size=\"10m\" --env-file .kamal/env/accessories/custom-busybox.env --label service=\"custom-busybox\" busybox:latest", new_command(:busybox).run.join(" ") end @@ -65,7 +66,7 @@ class CommandsAccessoryTest < ActiveSupport::TestCase @config[:logging] = { "driver" => "local", "options" => { "max-size" => "100m", "max-file" => "3" } } assert_equal \ - "docker run --name app-busybox --detach --restart unless-stopped --log-driver \"local\" --log-opt max-size=\"100m\" --log-opt max-file=\"3\" --env-file .kamal/env/accessories/app-busybox.env --label service=\"app-busybox\" busybox:latest", + "docker run --name custom-busybox --detach --restart unless-stopped --log-driver \"local\" --log-opt max-size=\"100m\" --log-opt max-file=\"3\" --env-file .kamal/env/accessories/custom-busybox.env --label service=\"custom-busybox\" busybox:latest", new_command(:busybox).run.join(" ") end diff --git a/test/commands/builder_test.rb b/test/commands/builder_test.rb index 22ed8575..51bb837c 100644 --- a/test/commands/builder_test.rb +++ b/test/commands/builder_test.rb @@ -111,6 +111,14 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder.push.join(" ") end + test "build with ssh agent socket" do + builder = new_builder_command(builder: { "ssh" => 'default=$SSH_AUTH_SOCK' }) + + assert_equal \ + "-t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile --ssh default=$SSH_AUTH_SOCK", + builder.target.build_options.join(" ") + end + test "validate image" do assert_equal "docker inspect -f '{{ .Config.Labels.service }}' dhh/app:123 | grep -x app || (echo \"Image dhh/app:123 is missing the `service` label\" && exit 1)", new_builder_command.validate_image.join(" ") end diff --git a/test/commands/prune_test.rb b/test/commands/prune_test.rb index 00db4ccc..c4a56a9a 100644 --- a/test/commands/prune_test.rb +++ b/test/commands/prune_test.rb @@ -23,7 +23,11 @@ class CommandsPruneTest < ActiveSupport::TestCase test "app containers" do assert_equal \ "docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +6 | while read container_id; do docker rm $container_id; done", - new_command.app_containers.join(" ") + new_command.app_containers(retain: 5).join(" ") + + assert_equal \ + "docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +4 | while read container_id; do docker rm $container_id; done", + new_command.app_containers(retain: 3).join(" ") end test "healthcheck containers" do diff --git a/test/configuration/accessory_test.rb b/test/configuration/accessory_test.rb index 522dc631..4b56be51 100644 --- a/test/configuration/accessory_test.rb +++ b/test/configuration/accessory_test.rb @@ -49,6 +49,7 @@ class ConfigurationAccessoryTest < ActiveSupport::TestCase } }, "monitoring" => { + "service" => "custom-monitoring", "image" => "monitoring:latest", "roles" => [ "web" ], "port" => "4321:4321", @@ -72,6 +73,7 @@ class ConfigurationAccessoryTest < ActiveSupport::TestCase test "service name" do assert_equal "app-mysql", @config.accessory(:mysql).service_name assert_equal "app-redis", @config.accessory(:redis).service_name + assert_equal "custom-monitoring", @config.accessory(:monitoring).service_name end test "port" do diff --git a/test/configuration/builder_test.rb b/test/configuration/builder_test.rb index da30d915..4f4bbc40 100644 --- a/test/configuration/builder_test.rb +++ b/test/configuration/builder_test.rb @@ -148,4 +148,14 @@ class ConfigurationBuilderTest < ActiveSupport::TestCase assert_equal "..", @config_with_builder_option.builder.context end + + test "ssh" do + assert_nil @config.builder.ssh + end + + test "setting ssh params" do + @deploy_with_builder_option[:builder] = { "ssh" => 'default=$SSH_AUTH_SOCK' } + + assert_equal 'default=$SSH_AUTH_SOCK', @config_with_builder_option.builder.ssh + end end diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 37b5b4a0..c538a82a 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -319,4 +319,12 @@ class ConfigurationTest < ActiveSupport::TestCase end assert_match /bar isn't defined/, error.message end + + test "retain_containers" do + assert_equal 5, @config.retain_containers + config = Kamal::Configuration.new(@deploy_with_roles.merge(retain_containers: 2)) + assert_equal 2, config.retain_containers + + assert_raises(ArgumentError) { Kamal::Configuration.new(@deploy_with_roles.merge(retain_containers: 0)) } + end end diff --git a/test/integration/docker/deployer/app/config/deploy.yml b/test/integration/docker/deployer/app/config/deploy.yml index ec070f6c..baedca99 100644 --- a/test/integration/docker/deployer/app/config/deploy.yml +++ b/test/integration/docker/deployer/app/config/deploy.yml @@ -24,9 +24,10 @@ traefik: args: accesslog: true accesslog.format: json - image: registry:4443/traefik:v2.9 + image: registry:4443/traefik:v2.10 accessories: busybox: + service: custom-busybox image: registry:4443/busybox:1.36.0 cmd: sh -c 'echo "Starting busybox..."; trap exit term; while true; do sleep 1; done' roles: diff --git a/test/integration/docker/deployer/setup.sh b/test/integration/docker/deployer/setup.sh index a2c9c6e8..0cd511d9 100755 --- a/test/integration/docker/deployer/setup.sh +++ b/test/integration/docker/deployer/setup.sh @@ -19,7 +19,7 @@ push_image_to_registry_4443() { install_kamal push_image_to_registry_4443 nginx 1-alpine-slim -push_image_to_registry_4443 traefik v2.9 +push_image_to_registry_4443 traefik v2.10 push_image_to_registry_4443 busybox 1.36.0 # .ssh is on a shared volume that persists between runs. Clean it up as the diff --git a/test/integration/main_test.rb b/test/integration/main_test.rb index a0364fb2..856781cb 100644 --- a/test/integration/main_test.rb +++ b/test/integration/main_test.rb @@ -32,7 +32,7 @@ class MainTest < IntegrationTest assert_match /Traefik Host: vm2/, details assert_match /App Host: vm1/, details assert_match /App Host: vm2/, details - assert_match /traefik:v2.9/, details + assert_match /traefik:v2.10/, details assert_match /registry:4443\/app:#{first_version}/, details audit = kamal :audit, capture: true diff --git a/test/integration/traefik_test.rb b/test/integration/traefik_test.rb index ed8a956f..6f735612 100644 --- a/test/integration/traefik_test.rb +++ b/test/integration/traefik_test.rb @@ -52,11 +52,11 @@ class TraefikTest < IntegrationTest private def assert_traefik_running - assert_match /traefik:v2.9 "\/entrypoint.sh/, traefik_details + assert_match /traefik:v2.10 "\/entrypoint.sh/, traefik_details end def assert_traefik_not_running - refute_match /traefik:v2.9 "\/entrypoint.sh/, traefik_details + refute_match /traefik:v2.10 "\/entrypoint.sh/, traefik_details end def traefik_details