From 66291a2aeadcb42c5e817ab5c58f6bb0ae5f2e23 Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Tue, 12 Sep 2023 10:45:01 +0100 Subject: [PATCH] Validate the build image Kamal needs images to have the service label so it can track them for pruning. Images built by Kamal will have the label, but externally built ones may not. Without it images will build up over time. The worst case is an outage if all the hosts disks fill up at the same time. We'll add a check for the label and halt if it is not there. --- lib/kamal/cli/build.rb | 1 + lib/kamal/commands/builder.rb | 2 +- lib/kamal/commands/builder/base.rb | 6 ++++++ test/cli/build_test.rb | 1 + test/commands/builder_test.rb | 4 ++++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/kamal/cli/build.rb b/lib/kamal/cli/build.rb index 3b64e89be..345310580 100644 --- a/lib/kamal/cli/build.rb +++ b/lib/kamal/cli/build.rb @@ -50,6 +50,7 @@ def pull execute *KAMAL.auditor.record("Pulled image with version #{KAMAL.config.version}"), verbosity: :debug execute *KAMAL.builder.clean, raise_on_non_zero_exit: false execute *KAMAL.builder.pull + execute *KAMAL.builder.validate_image end end end diff --git a/lib/kamal/commands/builder.rb b/lib/kamal/commands/builder.rb index 750482f25..bed0581da 100644 --- a/lib/kamal/commands/builder.rb +++ b/lib/kamal/commands/builder.rb @@ -1,7 +1,7 @@ require "active_support/core_ext/string/filters" class Kamal::Commands::Builder < Kamal::Commands::Base - delegate :create, :remove, :push, :clean, :pull, :info, to: :target + delegate :create, :remove, :push, :clean, :pull, :info, :validate_image, to: :target def name target.class.to_s.remove("Kamal::Commands::Builder::").underscore.inquiry diff --git a/lib/kamal/commands/builder/base.rb b/lib/kamal/commands/builder/base.rb index 19d44935e..8723fa454 100644 --- a/lib/kamal/commands/builder/base.rb +++ b/lib/kamal/commands/builder/base.rb @@ -21,6 +21,12 @@ def build_context config.builder.context end + def validate_image + pipe \ + docker(:inspect, "-f", "'{{ .Config.Labels.service }}'", config.absolute_image), + [:grep, "-x", config.service, "||", "(echo \"Image #{config.absolute_image} is missing the `service` label\" && exit 1)"] + end + private def build_tags diff --git a/test/cli/build_test.rb b/test/cli/build_test.rb index c64a49173..cd71e279c 100644 --- a/test/cli/build_test.rb +++ b/test/cli/build_test.rb @@ -57,6 +57,7 @@ class CliBuildTest < CliTestCase run_command("pull").tap do |output| assert_match /docker image rm --force dhh\/app:999/, output assert_match /docker pull dhh\/app:999/, output + assert_match "docker inspect -f '{{ .Config.Labels.service }}' dhh/app:999 | grep -x app || (echo \"Image dhh/app:999 is missing the `service` label\" && exit 1)", output end end diff --git a/test/commands/builder_test.rb b/test/commands/builder_test.rb index 1cc5939b1..c0256113f 100644 --- a/test/commands/builder_test.rb +++ b/test/commands/builder_test.rb @@ -103,6 +103,10 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder.push.join(" ") end + test "validate image" do + assert_equal "docker inspect -f '{{ .Config.Labels.service }}' dhh/app:123 | grep -x app || (echo \"Image dhh/app:123 is missing the `service` label\" && exit 1)", new_builder_command.validate_image.join(" ") + end + private def new_builder_command(additional_config = {}) Kamal::Commands::Builder.new(Kamal::Configuration.new(@config.merge(additional_config), version: "123"))