Check all hosts before rolling back

Hosts could end up out of sync with each other if prune commands are run
manually or when new hosts are added.

Before rolling back confirm that the required container is available on
all hosts and roles.
This commit is contained in:
Donal McBreen
2023-05-01 16:34:32 +01:00
parent 54881a0298
commit 7fe24d5048
2 changed files with 31 additions and 11 deletions

View File

@@ -236,15 +236,24 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
subcommand "lock", Mrsk::Cli::Lock subcommand "lock", Mrsk::Cli::Lock
private private
def container_available?(version, host: MRSK.primary_host) def container_available?(version)
available = nil begin
on(MRSK.hosts) do
on(host) do MRSK.roles_on(host).each do |role|
first_role = MRSK.roles_on(host).first container_id = capture_with_info(*MRSK.app(role: role).container_id_for_version(version))
available = capture_with_info(*MRSK.app(role: first_role).container_id_for_version(version)).present? raise "Container not found" unless container_id.present?
end
end
rescue SSHKit::Runner::ExecuteError => e
if e.message =~ /Container not found/
say "Cannot rollback: #{e.message}"
return false
else
raise
end
end end
available true
end end
def deploy_options def deploy_options

View File

@@ -145,7 +145,8 @@ class CliMainTest < CliTestCase
end end
test "rollback bad version" do test "rollback bad version" do
# Mrsk::Cli::Main.any_instance.stubs(:container_available?).returns(false) Thread.report_on_exception = false
run_command("details") # Preheat MRSK const run_command("details") # Preheat MRSK const
run_command("rollback", "nonsense").tap do |output| run_command("rollback", "nonsense").tap do |output|
@@ -155,9 +156,19 @@ class CliMainTest < CliTestCase
end end
test "rollback good version" do test "rollback good version" do
Mrsk::Cli::Main.any_instance.stubs(:container_available?).returns(true) SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--filter", "label=role=web", "--filter", "status=running", "--latest", "--format", "\"{{.Names}}\"", "|", "grep -oE \"\\-[^-]+$\"", "|", "cut -c 2-").returns("version-to-rollback\n").at_least_once .with(:docker, :container, :ls, "--all", "--filter", "name=^app-web-123$", "--quiet")
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--filter", "label=role=workers", "--filter", "status=running", "--latest", "--format", "\"{{.Names}}\"", "|", "grep -oE \"\\-[^-]+$\"", "|", "cut -c 2-").returns("version-to-rollback\n").at_least_once .returns("version-to-rollback\n").at_least_once
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
.with(:docker, :container, :ls, "--all", "--filter", "name=^app-workers-123$", "--quiet")
.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=web", "--filter", "status=running", "--latest", "--format", "\"{{.Names}}\"", "|", "grep -oE \"\\-[^-]+$\"", "|", "cut -c 2-")
.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", "--filter", "status=running", "--latest", "--format", "\"{{.Names}}\"", "|", "grep -oE \"\\-[^-]+$\"", "|", "cut -c 2-")
.returns("version-to-rollback\n").at_least_once
run_command("rollback", "123", config_file: "deploy_with_accessories").tap do |output| run_command("rollback", "123", config_file: "deploy_with_accessories").tap do |output|
assert_match "Start version 123", output assert_match "Start version 123", output