From 326711a3e02282a3e0d703d78727821419e15210 Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Fri, 5 May 2023 12:03:34 +0100 Subject: [PATCH] Fix aggressive prune breaking rollback In the image prune command --all overrides --dangling=true. This removes the image git sha image tag for the latest image which prevented us from rolling back to it. I've updated the integration test to now test deploy, redeploy and rollback. --- lib/mrsk/commands/prune.rb | 2 +- test/cli/prune_test.rb | 2 +- test/commands/prune_test.rb | 2 +- test/integration/deploy_test.rb | 73 ++++++++++++++++--- test/integration/docker/deployer/Dockerfile | 3 +- .../docker/deployer/app/Dockerfile | 1 + .../docker/deployer/update_app_rev.sh | 4 + 7 files changed, 73 insertions(+), 14 deletions(-) create mode 100755 test/integration/docker/deployer/update_app_rev.sh diff --git a/lib/mrsk/commands/prune.rb b/lib/mrsk/commands/prune.rb index 0ac779d5..79da58be 100644 --- a/lib/mrsk/commands/prune.rb +++ b/lib/mrsk/commands/prune.rb @@ -3,7 +3,7 @@ require "active_support/core_ext/numeric/time" class Mrsk::Commands::Prune < Mrsk::Commands::Base 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 def containers(keep_last: 5) diff --git a/test/cli/prune_test.rb b/test/cli/prune_test.rb index 40a1d80f..e07f3172 100644 --- a/test/cli/prune_test.rb +++ b/test/cli/prune_test.rb @@ -10,7 +10,7 @@ class CliPruneTest < CliTestCase test "images" do 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 diff --git a/test/commands/prune_test.rb b/test/commands/prune_test.rb index bd6a561d..436ed02f 100644 --- a/test/commands/prune_test.rb +++ b/test/commands/prune_test.rb @@ -10,7 +10,7 @@ class CommandsPruneTest < ActiveSupport::TestCase test "images" do 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(" ") end diff --git a/test/integration/deploy_test.rb b/test/integration/deploy_test.rb index 351dc5d2..cefde4cd 100644 --- a/test/integration/deploy_test.rb +++ b/test/integration/deploy_test.rb @@ -13,11 +13,36 @@ class DeployTest < ActiveSupport::TestCase end test "deploy" do + first_version = latest_app_version + assert_app_is_down 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 private @@ -34,23 +59,19 @@ class DeployTest < ActiveSupport::TestCase result end - def deployer_exec(*commands, capture: false) - if capture - stdouted { docker_compose("exec deployer #{commands.join(" ")}") } - else - docker_compose("exec deployer #{commands.join(" ")}", capture: capture) - end + def deployer_exec(*commands, **options) + docker_compose("exec deployer #{commands.join(" ")}", **options) end - def mrsk(*commands, capture: false) - deployer_exec(:mrsk, *commands, capture: capture) + def mrsk(*commands, **options) + deployer_exec(:mrsk, *commands, **options) end def assert_app_is_down assert_equal "502", app_response.code end - def assert_app_is_up + def assert_app_is_up(version: nil) code = app_response.code if code != "200" 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}" end 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 def app_response Net::HTTP.get_response(URI.parse("http://localhost:12345")) 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) timeout_at = Time.now + timeout while docker_compose("ps -a | tail -n +2 | grep -v '(healthy)' | wc -l", capture: true) != "0" diff --git a/test/integration/docker/deployer/Dockerfile b/test/integration/docker/deployer/Dockerfile index ccd1de39..e481a1b1 100644 --- a/test/integration/docker/deployer/Dockerfile +++ b/test/integration/docker/deployer/Dockerfile @@ -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 -COPY boot.sh . +COPY *.sh . COPY app/ . 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.name "Deployer" RUN git init && git add . && git commit -am "Initial version" +RUN git rev-parse HEAD > version HEALTHCHECK --interval=1s CMD pgrep sleep diff --git a/test/integration/docker/deployer/app/Dockerfile b/test/integration/docker/deployer/app/Dockerfile index b173cc99..768f1ccf 100644 --- a/test/integration/docker/deployer/app/Dockerfile +++ b/test/integration/docker/deployer/app/Dockerfile @@ -1,3 +1,4 @@ FROM nginx:1-alpine-slim COPY default.conf /etc/nginx/conf.d/default.conf +COPY version /usr/share/nginx/html/version diff --git a/test/integration/docker/deployer/update_app_rev.sh b/test/integration/docker/deployer/update_app_rev.sh new file mode 100755 index 00000000..430dc71b --- /dev/null +++ b/test/integration/docker/deployer/update_app_rev.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +git commit -am 'Update rev' --amend +git rev-parse HEAD > version