Skip existing containers on accessory boot
When booting an accessory, check for the container first and skip boot if it exists. This allows us to rerun `kamal setup` on hosts with accessories without raising an error. Fixes: https://github.com/basecamp/kamal/issues/488
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
require "active_support/core_ext/array/conversions"
|
require "active_support/core_ext/array/conversions"
|
||||||
|
require "concurrent/array"
|
||||||
|
|
||||||
class Kamal::Cli::Accessory < Kamal::Cli::Base
|
class Kamal::Cli::Accessory < Kamal::Cli::Base
|
||||||
desc "boot [NAME]", "Boot new accessory service on host (use NAME=all to boot all accessories)"
|
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
|
prepare(name) if prepare
|
||||||
|
|
||||||
with_accessory(name) do |accessory, hosts|
|
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)
|
directories(name)
|
||||||
upload(name)
|
upload(name)
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
|||||||
docker :container, :stop, service_name
|
docker :container, :stop, service_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def info
|
def info(all: false, quiet: false)
|
||||||
docker :ps, *service_filter
|
docker :ps, *("-a" if all), *("-q" if quiet), *service_filter
|
||||||
end
|
end
|
||||||
|
|
||||||
def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil)
|
def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil)
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ class AccessoryTest < IntegrationTest
|
|||||||
logs = kamal :accessory, :logs, :busybox, capture: true
|
logs = kamal :accessory, :logs, :busybox, capture: true
|
||||||
assert_match /Starting busybox.../, logs
|
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"
|
kamal :accessory, :remove, :busybox, "-y"
|
||||||
assert_accessory_not_running :busybox
|
assert_accessory_not_running :busybox
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class IntegrationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
teardown do
|
teardown do
|
||||||
if !passed? && ENV["DEBUG"]
|
if !passed? && ENV["DEBUG_CONTAINER_LOGS"]
|
||||||
[ :deployer, :vm1, :vm2, :shared, :load_balancer, :registry ].each do |container|
|
[ :deployer, :vm1, :vm2, :shared, :load_balancer, :registry ].each do |container|
|
||||||
puts
|
puts
|
||||||
puts "Logs for #{container}:"
|
puts "Logs for #{container}:"
|
||||||
|
|||||||
Reference in New Issue
Block a user