diff --git a/lib/mrsk/cli/main.rb b/lib/mrsk/cli/main.rb index 83f71c34d..a5dfdacb8 100644 --- a/lib/mrsk/cli/main.rb +++ b/lib/mrsk/cli/main.rb @@ -77,21 +77,26 @@ def rollback(version) with_lock do MRSK.config.version = version - if container_name_available?(MRSK.config.service_with_version) + if container_available?(version) say "Start version #{version}, then wait #{MRSK.config.readiness_delay}s for app to boot before stopping the old version...", :magenta cli = self old_version = nil on(MRSK.hosts) do |host| - old_version = capture_with_info(*MRSK.app.current_running_version).strip.presence + roles = MRSK.roles_on(host) - execute *MRSK.app.start + roles.each do |role| + app = MRSK.app(role: role) + old_version = capture_with_info(*app.current_running_version).strip.presence - if old_version - sleep MRSK.config.readiness_delay + execute *app.start - execute *MRSK.app.stop(version: old_version), raise_on_non_zero_exit: false + if old_version + sleep MRSK.config.readiness_delay + + execute *app.stop(version: old_version), raise_on_non_zero_exit: false + end end end @@ -214,10 +219,15 @@ def version subcommand "lock", Mrsk::Cli::Lock private - def container_name_available?(container_name, host: MRSK.primary_host) - container_names = nil - on(host) { container_names = capture_with_info(*MRSK.app.list_container_names).split("\n") } - Array(container_names).include?(container_name) + def container_available?(version, host: MRSK.primary_host) + available = nil + + on(host) do + first_role = MRSK.roles_on(host).first + available = capture_with_info(*MRSK.app(role: first_role).container_id_for_version(version)).present? + end + + available end def deploy_options diff --git a/test/cli/main_test.rb b/test/cli/main_test.rb index 8d00b277e..e08462b3b 100644 --- a/test/cli/main_test.rb +++ b/test/cli/main_test.rb @@ -120,32 +120,34 @@ class CliMainTest < CliTestCase end test "rollback bad version" do + # Mrsk::Cli::Main.any_instance.stubs(:container_available?).returns(false) run_command("details") # Preheat MRSK const run_command("rollback", "nonsense").tap do |output| - assert_match /docker container ls --all --filter label=service=app --format '{{ .Names }}'/, output + assert_match /docker container ls --all --filter name=\^app-web-nonsense\$ --quiet/, output assert_match /The app version 'nonsense' is not available as a container/, output end end test "rollback good version" do - Mrsk::Cli::Main.any_instance.stubs(:container_name_available?).returns(true) - SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--format", "\"{{.Names}}\"", "|", "sed 's/-/\\n/g'", "|", "tail -n 1").returns("version-to-rollback\n").at_least_once + Mrsk::Cli::Main.any_instance.stubs(:container_available?).returns(true) + SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--filter", "label=role=web", "--format", "\"{{.Names}}\"", "|", "sed 's/-/\\n/g'", "|", "tail -n 1").returns("version-to-rollback\n").at_least_once + SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--filter", "label=role=workers", "--format", "\"{{.Names}}\"", "|", "sed 's/-/\\n/g'", "|", "tail -n 1").returns("version-to-rollback\n").at_least_once run_command("rollback", "123", config_file: "deploy_with_accessories").tap do |output| assert_match "Start version 123", output - assert_match "docker start app-123", output - assert_match "docker container ls --all --filter name=^app-version-to-rollback$ --quiet | xargs docker stop", output, "Should stop the container that was previously running" + assert_match "docker start app-web-123", output + assert_match "docker container ls --all --filter name=^app-web-version-to-rollback$ --quiet | xargs docker stop", output, "Should stop the container that was previously running" end end test "rollback without old version" do - Mrsk::Cli::Main.any_instance.stubs(:container_name_available?).returns(true) - SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--format", "\"{{.Names}}\"", "|", "sed 's/-/\\n/g'", "|", "tail -n 1").returns("").at_least_once + Mrsk::Cli::Main.any_instance.stubs(:container_available?).returns(true) + SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--filter", "label=role=web", "--format", "\"{{.Names}}\"", "|", "sed 's/-/\\n/g'", "|", "tail -n 1").returns("").at_least_once run_command("rollback", "123").tap do |output| assert_match "Start version 123", output - assert_match "docker start app-123", output + assert_match "docker start app-web-123", output assert_no_match "docker stop", output end end