Remove only specific container needed for rebooting

This commit is contained in:
David Heinemeier Hansson
2023-02-03 13:20:03 +01:00
parent 004c154abb
commit 8024949fe7
4 changed files with 49 additions and 11 deletions

View File

@@ -21,10 +21,12 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
end
end
desc "reboot", "Reboot app on host (stop container, remove containers, start new container)"
desc "reboot", "Reboot app on host (stop container, remove container, start new container with latest image)"
def reboot
old_version = current_running_version
stop
remove_containers
remove_container old_version
boot
end
@@ -147,7 +149,12 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
remove_images
end
desc "remove_containers", "Remove app containers from servers"
desc "remove_container [VERSION]", "Remove app container with given version from servers"
def remove_container(version)
on(MRSK.hosts) { execute *MRSK.app.remove_container(version: version) }
end
desc "remove_containers", "Remove all app containers from servers"
def remove_containers
on(MRSK.hosts) { execute *MRSK.app.remove_containers }
end
@@ -184,9 +191,9 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
version
end
def current_running_version(host:)
def current_running_version(host: MRSK.primary_host)
version = nil
on(host) { version = capture_with_info(*MRSK.app.current_running_version).strip }
version
version.presence
end
end

View File

@@ -10,7 +10,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
docker :run,
"-d",
"--restart unless-stopped",
"--name", config.service_with_version,
"--name", service_with_version,
*rails_master_key_arg,
*role.env_args,
*config.volume_args,
@@ -20,7 +20,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
end
def start(version: config.version)
docker :start, "#{config.service}-#{version}"
docker :start, service_with_version(version)
end
def current_container_id
@@ -84,6 +84,12 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
docker :container, :ls, "-a", *service_filter
end
def remove_container(version:)
pipe \
container_id_for(container_name: service_with_version(version)),
docker(:container, :rm)
end
def remove_containers
docker :container, :prune, "-f", *service_filter
end
@@ -97,6 +103,14 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
end
private
def service_with_version(version = nil)
if version
"#{config.service}-#{version}"
else
config.service_with_version
end
end
def service_filter
[ "--filter", "label=service=#{config.service}" ]
end

View File

@@ -1,5 +1,9 @@
module Mrsk::Commands::Concerns
module Repository
def container_id_for(container_name:)
docker :container, :ls, "-a", "-f", "name=#{container_name}", "-q"
end
def current_running_version
# FIXME: Find more graceful way to extract the version from "app-version" than using sed and tail!
pipe \

View File

@@ -5,11 +5,24 @@ class CliAppTest < CliTestCase
assert_match /Running docker run -d --restart unless-stopped/, run_command("boot")
end
test "reboot" do
test "reboot to default version" do
run_command("reboot").tap do |output|
assert_match /docker stop/, output
assert_match /docker container prune/, output
assert_match /docker run -d --restart unless-stopped/, output
assert_match /docker ps --filter label=service=app/, output # Find current container
assert_match /docker stop/, output # Stop old container
assert_match /docker container rm/, output # Remove old container
assert_match /docker run -d --restart unless-stopped .* dhh\/app:999/, output # Start new container
end
end
test "reboot to specific version" do
run_command("reboot", "--version", "456").tap do |output|
assert_match /docker run -d --restart unless-stopped .* dhh\/app:456/, output
end
end
test "remove_container" do
run_command("remove_container", "1234567").tap do |output|
assert_match /docker container ls -a -f name=app-1234567 -q | docker container rm/, output
end
end