diff --git a/lib/kamal/cli/accessory.rb b/lib/kamal/cli/accessory.rb index c95cbb1e..735d554e 100644 --- a/lib/kamal/cli/accessory.rb +++ b/lib/kamal/cli/accessory.rb @@ -1,4 +1,5 @@ require "active_support/core_ext/array/conversions" +require "concurrent/array" class Kamal::Cli::Accessory < Kamal::Cli::Base desc "boot [NAME]", "Boot new accessory service on host (use NAME=all to boot all accessories)" @@ -10,6 +11,16 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base prepare(name) if prepare with_accessory(name) do |accessory, hosts| + booted_hosts = Concurrent::Array.new + on(hosts) do |host| + booted_hosts << host.to_s if capture_with_info(*accessory.info(all: true, quiet: true)).strip.presence + end + + if booted_hosts.any? + say "Skipping booting `#{name}` on #{booted_hosts.sort.join(", ")}, a container already exists", :yellow + hosts -= booted_hosts + end + directories(name) upload(name) @@ -275,11 +286,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base end def accessory_hosts(accessory) - if KAMAL.specific_hosts&.any? - KAMAL.specific_hosts & accessory.hosts - else - accessory.hosts - end + KAMAL.accessory_hosts & accessory.hosts end def remove_accessory(name) diff --git a/lib/kamal/commands/accessory.rb b/lib/kamal/commands/accessory.rb index 77ceb607..60279dfc 100644 --- a/lib/kamal/commands/accessory.rb +++ b/lib/kamal/commands/accessory.rb @@ -37,8 +37,8 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base docker :container, :stop, service_name end - def info - docker :ps, *service_filter + def info(all: false, quiet: false) + docker :ps, *("-a" if all), *("-q" if quiet), *service_filter end def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil) diff --git a/test/cli/accessory_test.rb b/test/cli/accessory_test.rb index cc517e59..c11426c0 100644 --- a/test/cli/accessory_test.rb +++ b/test/cli/accessory_test.rb @@ -251,6 +251,19 @@ class CliAccessoryTest < CliTestCase end end + test "boot with web role filter" do + run_command("boot", "redis", "-r", "web").tap do |output| + assert_match "docker run --name app-redis --detach --restart unless-stopped --network kamal --log-opt max-size=\"10m\" --publish 6379:6379 --env-file .kamal/apps/app/env/accessories/redis.env --volume $PWD/app-redis/data:/data --label service=\"app-redis\" redis:latest on 1.1.1.1", output + assert_match "docker run --name app-redis --detach --restart unless-stopped --network kamal --log-opt max-size=\"10m\" --publish 6379:6379 --env-file .kamal/apps/app/env/accessories/redis.env --volume $PWD/app-redis/data:/data --label service=\"app-redis\" redis:latest on 1.1.1.2", output + end + end + + test "boot with workers role filter" do + run_command("boot", "redis", "-r", "workers").tap do |output| + assert_no_match "docker run", output + end + end + private def run_command(*command) stdouted { Kamal::Cli::Accessory.start([ *command, "-c", "test/fixtures/deploy_with_accessories_with_different_registries.yml" ]) } diff --git a/test/integration/accessory_test.rb b/test/integration/accessory_test.rb index 0ed7a7b9..f5ce21de 100644 --- a/test/integration/accessory_test.rb +++ b/test/integration/accessory_test.rb @@ -17,6 +17,9 @@ class AccessoryTest < IntegrationTest logs = kamal :accessory, :logs, :busybox, capture: true assert_match /Starting busybox.../, logs + boot = kamal :accessory, :boot, :busybox, capture: true + assert_match /Skipping booting `busybox` on vm1, vm2, a container already exists/, boot + kamal :accessory, :remove, :busybox, "-y" assert_accessory_not_running :busybox end diff --git a/test/integration/integration_test.rb b/test/integration/integration_test.rb index 631d8fc4..ef92a278 100644 --- a/test/integration/integration_test.rb +++ b/test/integration/integration_test.rb @@ -11,7 +11,7 @@ class IntegrationTest < ActiveSupport::TestCase end teardown do - if !passed? && ENV["DEBUG"] + if !passed? && ENV["DEBUG_CONTAINER_LOGS"] [ :deployer, :vm1, :vm2, :shared, :load_balancer, :registry ].each do |container| puts puts "Logs for #{container}:"