diff --git a/lib/kamal/cli/app.rb b/lib/kamal/cli/app.rb index b4de978d..3ce88a1a 100644 --- a/lib/kamal/cli/app.rb +++ b/lib/kamal/cli/app.rb @@ -136,7 +136,10 @@ class Kamal::Cli::App < Kamal::Cli::Base roles = KAMAL.roles_on(host) roles.each do |role| - cli.send(:stale_versions, host: host, role: role).each do |version| + versions = capture_with_info(*KAMAL.app(role: role).list_versions, raise_on_non_zero_exit: false).split("\n") + versions -= [ capture_with_info(*KAMAL.app(role: role).current_running_version, raise_on_non_zero_exit: false).strip ] + + versions.each do |version| if stop puts_by_host host, "Stopping stale container for role #{role} with version #{version}" execute *KAMAL.app(role: role).stop(version: version), raise_on_non_zero_exit: false @@ -272,17 +275,6 @@ class Kamal::Cli::App < Kamal::Cli::Base version.presence end - def stale_versions(host:, role:) - versions = nil - on(host) do - versions = \ - capture_with_info(*KAMAL.app(role: role).list_versions, raise_on_non_zero_exit: false) - .split("\n") - .drop(1) - end - versions - end - def version_or_latest options[:version] || KAMAL.config.latest_tag end diff --git a/lib/kamal/commands/app.rb b/lib/kamal/commands/app.rb index 12d35bc6..15992640 100644 --- a/lib/kamal/commands/app.rb +++ b/lib/kamal/commands/app.rb @@ -49,9 +49,7 @@ class Kamal::Commands::App < Kamal::Commands::Base def current_running_container_id - pipe \ - shell(chain(latest_image_container_id, latest_container_id)), - [ :head, "-1" ] + current_running_container(format: "--quiet") end def container_id_for_version(version, only_running: false) @@ -60,8 +58,7 @@ class Kamal::Commands::App < Kamal::Commands::Base def current_running_version pipe \ - shell(chain(latest_image_container_name, latest_container_name)), - [ :head, "-1" ], + current_running_container(format: "--format '{{.Names}}'"), extract_version_from_name end @@ -90,28 +87,18 @@ class Kamal::Commands::App < Kamal::Commands::Base docker :image, :ls, *argumentize("--filter", "reference=#{config.latest_image}"), "--format", "'{{.ID}}'" end - def latest_image_container_id - latest_image_container format: "--quiet" + def current_running_container(format:) + pipe \ + shell(chain(latest_image_container(format: format), latest_container(format: format))), + [ :head, "-1" ] end - def latest_container_id - latest_container format: "--quiet" + def latest_image_container(format:) + latest_container format: format, filters: [ "ancestor=$(#{latest_image_id.join(" ")})" ] end - def latest_image_container_name - latest_image_container format: "--format '{{.Names}}'" - end - - def latest_container_name - latest_container format: "--format '{{.Names}}'" - end - - def latest_image_container(format: nil) - docker :ps, "--latest", *format, *filter_args(statuses: ACTIVE_DOCKER_STATUSES), "--filter", "ancestor=$(#{latest_image_id.join(" ")})" - end - - def latest_container(format:) - docker :ps, "--latest", *format, *filter_args(statuses: ACTIVE_DOCKER_STATUSES) + def latest_container(format:, filters: nil) + docker :ps, "--latest", *format, *filter_args(statuses: ACTIVE_DOCKER_STATUSES), argumentize("--filter", filters) end def filter_args(statuses: nil) diff --git a/test/cli/app_test.rb b/test/cli/app_test.rb index 25c3266e..ab0eff51 100644 --- a/test/cli/app_test.rb +++ b/test/cli/app_test.rb @@ -107,7 +107,11 @@ class CliAppTest < CliTestCase test "stale_containers" do SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) .with(:docker, :ps, "--filter", "label=service=app", "--filter", "label=role=web", "--format", "\"{{.Names}}\"", "|", "while read line; do echo ${line#app-web-}; done", raise_on_non_zero_exit: false) - .returns("12345678\n87654321") + .returns("12345678\n87654321\n") + + SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) + .with(:sh, "-c", "'docker ps --latest --format '\\''{{.Names}}'\\'' --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --format '\\''{{.Names}}'\\'' --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting'", "|", :head, "-1", "|", "while read line; do echo ${line#app-web-}; done", raise_on_non_zero_exit: false) + .returns("12345678\n") run_command("stale_containers").tap do |output| assert_match /Detected stale container for role web with version 87654321/, output @@ -117,7 +121,11 @@ class CliAppTest < CliTestCase test "stop stale_containers" do SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) .with(:docker, :ps, "--filter", "label=service=app", "--filter", "label=role=web", "--format", "\"{{.Names}}\"", "|", "while read line; do echo ${line#app-web-}; done", raise_on_non_zero_exit: false) - .returns("12345678\n87654321") + .returns("12345678\n87654321\n") + + SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) + .with(:sh, "-c", "'docker ps --latest --format '\\''{{.Names}}'\\'' --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --format '\\''{{.Names}}'\\'' --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting'", "|", :head, "-1", "|", "while read line; do echo ${line#app-web-}; done", raise_on_non_zero_exit: false) + .returns("12345678\n") run_command("stale_containers", "--stop").tap do |output| assert_match /Stopping stale container for role web with version 87654321/, output