From 87cb8c1f71a165883e70b45d85b592087800afef Mon Sep 17 00:00:00 2001 From: Yoel Cabo Date: Sun, 12 Nov 2023 09:39:07 +0100 Subject: [PATCH 1/2] fix: allow configurations without web roles --- lib/kamal/cli/healthcheck.rb | 1 + lib/kamal/commander.rb | 4 ++-- lib/kamal/commands/healthcheck.rb | 1 + lib/kamal/configuration.rb | 10 +++++++--- test/cli/healthcheck_test.rb | 9 +++++++-- test/configuration_test.rb | 6 +++--- test/fixtures/deploy_workers_only.yml | 10 ++++++++++ 7 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 test/fixtures/deploy_workers_only.yml diff --git a/lib/kamal/cli/healthcheck.rb b/lib/kamal/cli/healthcheck.rb index 5a72e6864..e9bd6c2ea 100644 --- a/lib/kamal/cli/healthcheck.rb +++ b/lib/kamal/cli/healthcheck.rb @@ -3,6 +3,7 @@ class Kamal::Cli::Healthcheck < Kamal::Cli::Base desc "perform", "Health check current app version" def perform + return unless KAMAL.primary_role.running_traefik? on(KAMAL.primary_host) do begin execute *KAMAL.healthcheck.run diff --git a/lib/kamal/commander.rb b/lib/kamal/commander.rb index 9ba3be122..869568ae0 100644 --- a/lib/kamal/commander.rb +++ b/lib/kamal/commander.rb @@ -24,7 +24,7 @@ def configure(**kwargs) attr_reader :specific_roles, :specific_hosts def specific_primary! - self.specific_hosts = [ config.primary_web_host ] + self.specific_hosts = [ config.primary_host ] end def specific_roles=(role_names) @@ -36,7 +36,7 @@ def specific_hosts=(hosts) end def primary_host - specific_hosts&.first || specific_roles&.first&.primary_host || config.primary_web_host + specific_hosts&.first || specific_roles&.first&.primary_host || config.primary_host end def primary_role diff --git a/lib/kamal/commands/healthcheck.rb b/lib/kamal/commands/healthcheck.rb index 5adc02445..6abe9bbdf 100644 --- a/lib/kamal/commands/healthcheck.rb +++ b/lib/kamal/commands/healthcheck.rb @@ -2,6 +2,7 @@ class Kamal::Commands::Healthcheck < Kamal::Commands::Base def run web = config.role(:web) + return unless web.present? docker :run, "--detach", diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index fc881c069..b4a0ecd5f 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -89,8 +89,12 @@ def all_hosts roles.flat_map(&:hosts).uniq end - def primary_web_host - role(:web).primary_host + def primary_host + primary_role.primary_host + end + + def primary_role + role(:web) || roles.first end def traefik_hosts @@ -208,7 +212,7 @@ def to_h { roles: role_names, hosts: all_hosts, - primary_host: primary_web_host, + primary_host: primary_host, version: version, repository: repository, absolute_image: absolute_image, diff --git a/test/cli/healthcheck_test.rb b/test/cli/healthcheck_test.rb index e76e43e13..c4554d4f5 100644 --- a/test/cli/healthcheck_test.rb +++ b/test/cli/healthcheck_test.rb @@ -64,9 +64,14 @@ class CliHealthcheckTest < CliTestCase end assert_match "container not ready (unhealthy)", exception.message end + + test "does not perform if primary does not have traefik" do + SSHKit::Backend::Abstract.any_instance.expects(:execute).never + run_command("perform", config_file: "test/fixtures/deploy_workers_only.yml") + end private - def run_command(*command) - stdouted { Kamal::Cli::Healthcheck.start([*command, "-c", "test/fixtures/deploy_with_accessories.yml"]) } + def run_command(*command, config_file: "test/fixtures/deploy_with_accessories.yml") + stdouted { Kamal::Cli::Healthcheck.start([*command, "-c", config_file]) } end end diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 5b9f4cc9b..62693b2a8 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -58,9 +58,9 @@ class ConfigurationTest < ActiveSupport::TestCase assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3" ], @config_with_roles.all_hosts end - test "primary web host" do - assert_equal "1.1.1.1", @config.primary_web_host - assert_equal "1.1.1.1", @config_with_roles.primary_web_host + test "primary host" do + assert_equal "1.1.1.1", @config.primary_host + assert_equal "1.1.1.1", @config_with_roles.primary_host end test "traefik hosts" do diff --git a/test/fixtures/deploy_workers_only.yml b/test/fixtures/deploy_workers_only.yml new file mode 100644 index 000000000..f12e650e6 --- /dev/null +++ b/test/fixtures/deploy_workers_only.yml @@ -0,0 +1,10 @@ +service: app +image: dhh/app +servers: + workers: + hosts: + - 1.1.1.1 + - 1.1.1.2 +registry: + username: user + password: pw From 887b7dd46d77f8a330a31bfe67cd062cfd66f84c Mon Sep 17 00:00:00 2001 From: Yoel Cabo Date: Tue, 14 Nov 2023 11:29:07 +0100 Subject: [PATCH 2/2] Do not invoke healthcheck on deploy when no web role --- lib/kamal/cli/healthcheck.rb | 2 +- lib/kamal/cli/main.rb | 6 ++++-- lib/kamal/commands/healthcheck.rb | 1 - test/cli/healthcheck_test.rb | 9 +++++++-- test/cli/main_test.rb | 15 +++++++++++++++ 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/kamal/cli/healthcheck.rb b/lib/kamal/cli/healthcheck.rb index e9bd6c2ea..54d01c031 100644 --- a/lib/kamal/cli/healthcheck.rb +++ b/lib/kamal/cli/healthcheck.rb @@ -3,7 +3,7 @@ class Kamal::Cli::Healthcheck < Kamal::Cli::Base desc "perform", "Health check current app version" def perform - return unless KAMAL.primary_role.running_traefik? + raise "The primary host is not configured to run Traefik" unless KAMAL.config.primary_role.running_traefik? on(KAMAL.primary_host) do begin execute *KAMAL.healthcheck.run diff --git a/lib/kamal/cli/main.rb b/lib/kamal/cli/main.rb index b1f54abab..c8f0411df 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -38,8 +38,10 @@ def deploy say "Ensure Traefik is running...", :magenta invoke "kamal:cli:traefik:boot", [], invoke_options - say "Ensure app can pass healthcheck...", :magenta - invoke "kamal:cli:healthcheck:perform", [], invoke_options + if KAMAL.config.primary_role.running_traefik? + say "Ensure app can pass healthcheck...", :magenta + invoke "kamal:cli:healthcheck:perform", [], invoke_options + end say "Detect stale containers...", :magenta invoke "kamal:cli:app:stale_containers", [], invoke_options.merge(stop: true) diff --git a/lib/kamal/commands/healthcheck.rb b/lib/kamal/commands/healthcheck.rb index 6abe9bbdf..5adc02445 100644 --- a/lib/kamal/commands/healthcheck.rb +++ b/lib/kamal/commands/healthcheck.rb @@ -2,7 +2,6 @@ class Kamal::Commands::Healthcheck < Kamal::Commands::Base def run web = config.role(:web) - return unless web.present? docker :run, "--detach", diff --git a/test/cli/healthcheck_test.rb b/test/cli/healthcheck_test.rb index c4554d4f5..3cba78bca 100644 --- a/test/cli/healthcheck_test.rb +++ b/test/cli/healthcheck_test.rb @@ -65,9 +65,14 @@ class CliHealthcheckTest < CliTestCase assert_match "container not ready (unhealthy)", exception.message end - test "does not perform if primary does not have traefik" do + test "raises an exception if primary does not have traefik" do SSHKit::Backend::Abstract.any_instance.expects(:execute).never - run_command("perform", config_file: "test/fixtures/deploy_workers_only.yml") + + exception = assert_raises do + run_command("perform", config_file: "test/fixtures/deploy_workers_only.yml") + end + + assert_equal "The primary host is not configured to run Traefik", exception.message end private diff --git a/test/cli/main_test.rb b/test/cli/main_test.rb index a19ff90e7..852602c6a 100644 --- a/test/cli/main_test.rb +++ b/test/cli/main_test.rb @@ -122,6 +122,21 @@ class CliMainTest < CliTestCase refute_match /Running the post-deploy hook.../, output end end + + test "deploy without healthcheck if primary host doesn't have traefik" do + invoke_options = { "config_file" => "test/fixtures/deploy_workers_only.yml", "version" => "999", "skip_hooks" => false } + + Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:healthcheck:perform", [], invoke_options).never + + Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:registry:login", [], invoke_options) + Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:build:deliver", [], invoke_options) + Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:traefik:boot", [], invoke_options) + Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:app:stale_containers", [], invoke_options.merge(stop: true)) + Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:app:boot", [], invoke_options) + Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:prune:all", [], invoke_options) + + run_command("deploy", config_file: "deploy_workers_only") + end test "deploy with missing secrets" do invoke_options = { "config_file" => "test/fixtures/deploy_with_secrets.yml", "version" => "999", "skip_hooks" => false }