Merge pull request #270 from basecamp/fix-aggressive-prune-breaking-rollback

Fix aggressive prune breaking rollback
This commit is contained in:
David Heinemeier Hansson
2023-05-05 14:28:22 +02:00
committed by GitHub
7 changed files with 73 additions and 14 deletions

View File

@@ -3,7 +3,7 @@ require "active_support/core_ext/numeric/time"
class Mrsk::Commands::Prune < Mrsk::Commands::Base class Mrsk::Commands::Prune < Mrsk::Commands::Base
def images def images
docker :image, :prune, "--all", "--force", "--filter", "label=service=#{config.service}", "--filter", "dangling=true" docker :image, :prune, "--force", "--filter", "label=service=#{config.service}", "--filter", "dangling=true"
end end
def containers(keep_last: 5) def containers(keep_last: 5)

View File

@@ -10,7 +10,7 @@ class CliPruneTest < CliTestCase
test "images" do test "images" do
run_command("images").tap do |output| run_command("images").tap do |output|
assert_match /docker image prune --all --force --filter label=service=app --filter dangling=true on 1.1.1.\d/, output assert_match /docker image prune --force --filter label=service=app --filter dangling=true on 1.1.1.\d/, output
end end
end end

View File

@@ -10,7 +10,7 @@ class CommandsPruneTest < ActiveSupport::TestCase
test "images" do test "images" do
assert_equal \ assert_equal \
"docker image prune --all --force --filter label=service=app --filter dangling=true", "docker image prune --force --filter label=service=app --filter dangling=true",
new_command.images.join(" ") new_command.images.join(" ")
end end

View File

@@ -13,11 +13,36 @@ class DeployTest < ActiveSupport::TestCase
end end
test "deploy" do test "deploy" do
first_version = latest_app_version
assert_app_is_down assert_app_is_down
mrsk :deploy mrsk :deploy
assert_app_is_up assert_app_is_up version: first_version
second_version = update_app_rev
mrsk :redeploy
assert_app_is_up version: second_version
mrsk :rollback, first_version
assert_app_is_up version: first_version
details = mrsk :details, capture: true
assert_match /Traefik Host: vm1/, details
assert_match /Traefik Host: vm2/, details
assert_match /App Host: vm1/, details
assert_match /App Host: vm2/, details
assert_match /traefik:v2.9/, details
assert_match /registry:4443\/app:#{first_version}/, details
audit = mrsk :audit, capture: true
assert_match /Booted app version #{first_version}.*Booted app version #{second_version}.*Booted app version #{first_version}.*/m, audit
end end
private private
@@ -34,23 +59,19 @@ class DeployTest < ActiveSupport::TestCase
result result
end end
def deployer_exec(*commands, capture: false) def deployer_exec(*commands, **options)
if capture docker_compose("exec deployer #{commands.join(" ")}", **options)
stdouted { docker_compose("exec deployer #{commands.join(" ")}") }
else
docker_compose("exec deployer #{commands.join(" ")}", capture: capture)
end
end end
def mrsk(*commands, capture: false) def mrsk(*commands, **options)
deployer_exec(:mrsk, *commands, capture: capture) deployer_exec(:mrsk, *commands, **options)
end end
def assert_app_is_down def assert_app_is_down
assert_equal "502", app_response.code assert_equal "502", app_response.code
end end
def assert_app_is_up def assert_app_is_up(version: nil)
code = app_response.code code = app_response.code
if code != "200" if code != "200"
puts "Got response code #{code}, here are the traefik logs:" puts "Got response code #{code}, here are the traefik logs:"
@@ -60,12 +81,44 @@ class DeployTest < ActiveSupport::TestCase
puts "Tried to get the response code again and got #{app_response.code}" puts "Tried to get the response code again and got #{app_response.code}"
end end
assert_equal "200", code assert_equal "200", code
assert_app_version(version) if version
end
def assert_app_not_found
assert_equal "404", app_response.code
end
def wait_for_app_to_be_up(timeout: 10, up_count: 3)
timeout_at = Time.now + timeout
up_times = 0
response = app_response
while up_times < up_count && timeout_at > Time.now
sleep 0.1
up_times += 1 if response.code == "200"
response = app_response
end
assert_equal up_times, up_count
end end
def app_response def app_response
Net::HTTP.get_response(URI.parse("http://localhost:12345")) Net::HTTP.get_response(URI.parse("http://localhost:12345"))
end end
def update_app_rev
deployer_exec "./update_app_rev.sh"
latest_app_version
end
def latest_app_version
deployer_exec("cat version", capture: true)
end
def assert_app_version(version)
actual_version = Net::HTTP.get_response(URI.parse("http://localhost:12345/version")).body.strip
assert_equal version, actual_version
end
def wait_for_healthy(timeout: 20) def wait_for_healthy(timeout: 20)
timeout_at = Time.now + timeout timeout_at = Time.now + timeout
while docker_compose("ps -a | tail -n +2 | grep -v '(healthy)' | wc -l", capture: true) != "0" while docker_compose("ps -a | tail -n +2 | grep -v '(healthy)' | wc -l", capture: true) != "0"

View File

@@ -14,7 +14,7 @@ RUN echo \
RUN apt-get update --fix-missing && apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin RUN apt-get update --fix-missing && apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
COPY boot.sh . COPY *.sh .
COPY app/ . COPY app/ .
RUN ln -s /shared/ssh /root/.ssh RUN ln -s /shared/ssh /root/.ssh
@@ -23,6 +23,7 @@ RUN mkdir -p /etc/docker/certs.d/registry:4443 && ln -s /shared/certs/domain.crt
RUN git config --global user.email "deployer@example.com" RUN git config --global user.email "deployer@example.com"
RUN git config --global user.name "Deployer" RUN git config --global user.name "Deployer"
RUN git init && git add . && git commit -am "Initial version" RUN git init && git add . && git commit -am "Initial version"
RUN git rev-parse HEAD > version
HEALTHCHECK --interval=1s CMD pgrep sleep HEALTHCHECK --interval=1s CMD pgrep sleep

View File

@@ -1,3 +1,4 @@
FROM nginx:1-alpine-slim FROM nginx:1-alpine-slim
COPY default.conf /etc/nginx/conf.d/default.conf COPY default.conf /etc/nginx/conf.d/default.conf
COPY version /usr/share/nginx/html/version

View File

@@ -0,0 +1,4 @@
#!/bin/bash
git commit -am 'Update rev' --amend
git rev-parse HEAD > version