diff --git a/lib/kamal/cli/healthcheck.rb b/lib/kamal/cli/healthcheck.rb index 5a72e686..b3dbf6bd 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 + raise "The primary host is not configured to run Traefik" unless KAMAL.config.role(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 b1f54aba..6adc36fe 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -38,8 +38,10 @@ class Kamal::Cli::Main < Kamal::Cli::Base 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.role(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/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index 6d356c60..20bbe71a 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -84,13 +84,12 @@ registry: # limit: 10 # Can also specify as a percentage of total hosts, such as "25%" # wait: 2 -# Configure the role used to determine the primary_web_host. This host takes +# Configure the role used to determine the primary_host. This host takes # deploy locks, runs health checks during the deploy, and follow logs, etc. -# This role should have traefik enabled. # # Caution: there's no support for role renaming yet, so be careful to cleanup # the previous role on the deployed hosts. -# primary_web_role: web +# primary_role: web # Controls if we abort when see a role with no hosts. Disabling this may be # useful for more complex deploy configurations. diff --git a/lib/kamal/commander.rb b/lib/kamal/commander.rb index d97f1991..35939fe7 100644 --- a/lib/kamal/commander.rb +++ b/lib/kamal/commander.rb @@ -24,7 +24,7 @@ class Kamal::Commander 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 @@ class Kamal::Commander 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 05379ab6..35bf9562 100644 --- a/lib/kamal/commands/healthcheck.rb +++ b/lib/kamal/commands/healthcheck.rb @@ -1,7 +1,7 @@ class Kamal::Commands::Healthcheck < Kamal::Commands::Base def run - web = config.role(config.primary_web_role) + primary = config.role(config.primary_role) docker :run, "--detach", @@ -9,12 +9,12 @@ class Kamal::Commands::Healthcheck < Kamal::Commands::Base "--publish", "#{exposed_port}:#{config.healthcheck["port"]}", "--label", "service=#{config.healthcheck_service}", "-e", "KAMAL_CONTAINER_NAME=\"#{config.healthcheck_service}\"", - *web.env_args, - *web.health_check_args(cord: false), + *primary.env_args, + *primary.health_check_args(cord: false), *config.volume_args, - *web.option_args, + *primary.option_args, config.absolute_image, - web.cmd + primary.cmd end def status diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index fd79d53e..e5ecbb53 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -91,8 +91,8 @@ class Kamal::Configuration roles.flat_map(&:hosts).uniq end - def primary_web_host - role(primary_web_role)&.primary_host + def primary_host + role(primary_role)&.primary_host end def traefik_roles @@ -208,8 +208,8 @@ class Kamal::Configuration raw_config.asset_path end - def primary_web_role - raw_config.primary_web_role || "web" + def primary_role + raw_config.primary_role || "web" end def allow_empty_roles? @@ -225,7 +225,7 @@ class Kamal::Configuration { roles: role_names, hosts: all_hosts, - primary_host: primary_web_host, + primary_host: primary_host, version: version, repository: repository, absolute_image: absolute_image, @@ -264,16 +264,12 @@ class Kamal::Configuration raise ArgumentError, "You must specify a password for the registry in config/deploy.yml (or set the ENV variable if that's used)" end - unless role_names.include?(primary_web_role) - raise ArgumentError, "The primary_web_role #{primary_web_role} isn't defined" + unless role_names.include?(primary_role) + raise ArgumentError, "The primary_role #{primary_role} isn't defined" end - unless traefik_role_names.include?(primary_web_role) - raise ArgumentError, "Role #{primary_web_role} needs to have traefik enabled" - end - - if role(primary_web_role).hosts.empty? - raise ArgumentError, "No servers specified for the #{primary_web_role} primary_web_role" + if role(primary_role).hosts.empty? + raise ArgumentError, "No servers specified for the #{primary_role} primary_role" end unless allow_empty_roles? diff --git a/lib/kamal/configuration/role.rb b/lib/kamal/configuration/role.rb index e4c3ff5f..da88d406 100644 --- a/lib/kamal/configuration/role.rb +++ b/lib/kamal/configuration/role.rb @@ -93,7 +93,15 @@ class Kamal::Configuration::Role def running_traefik? - name.web? || specializations["traefik"] + if specializations["traefik"].nil? + primary? + else + specializations["traefik"] + end + end + + def primary? + @config.primary_role == name end diff --git a/test/cli/healthcheck_test.rb b/test/cli/healthcheck_test.rb index e76e43e1..3cba78bc 100644 --- a/test/cli/healthcheck_test.rb +++ b/test/cli/healthcheck_test.rb @@ -64,9 +64,19 @@ class CliHealthcheckTest < CliTestCase end assert_match "container not ready (unhealthy)", exception.message end + + test "raises an exception if primary does not have traefik" do + SSHKit::Backend::Abstract.any_instance.expects(:execute).never + + 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 - 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/cli/main_test.rb b/test/cli/main_test.rb index 58465c7b..8b152d52 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 } diff --git a/test/configuration_test.rb b/test/configuration_test.rb index d141ad10..392b6afb 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 @@ -289,27 +289,23 @@ class ConfigurationTest < ActiveSupport::TestCase assert_equal "foo", Kamal::Configuration.new(@deploy.merge!(asset_path: "foo")).asset_path end - test "primary web role" do - assert_equal "web", @config.primary_web_role + test "primary role" do + assert_equal "web", @config.primary_role config = Kamal::Configuration.new(@deploy_with_roles.deep_merge({ - servers: { "alternate_web" => { "hosts" => [ "1.1.1.4", "1.1.1.5" ] , "traefik" => true } }, - primary_web_role: "alternate_web" } )) + servers: { "alternate_web" => { "hosts" => [ "1.1.1.4", "1.1.1.5" ] } }, + primary_role: "alternate_web" } )) - assert_equal "alternate_web", config.primary_web_role - assert_equal "1.1.1.4", config.primary_web_host + + assert_equal "alternate_web", config.primary_role + assert_equal "1.1.1.4", config.primary_host + assert config.role(:alternate_web).primary? + assert config.role(:alternate_web).running_traefik? end - test "primary web role no traefik" do + test "primary role missing" do error = assert_raises(ArgumentError) do - Kamal::Configuration.new(@deploy_with_roles.merge(primary_web_role: "workers")) - end - assert_match /workers needs to have traefik enabled/, error.message - end - - test "primary web role missing" do - error = assert_raises(ArgumentError) do - Kamal::Configuration.new(@deploy.merge(primary_web_role: "bar")) + Kamal::Configuration.new(@deploy.merge(primary_role: "bar")) end assert_match /bar isn't defined/, error.message end diff --git a/test/fixtures/deploy_primary_web_role_override.yml b/test/fixtures/deploy_primary_web_role_override.yml index 264819fe..e372c602 100644 --- a/test/fixtures/deploy_primary_web_role_override.yml +++ b/test/fixtures/deploy_primary_web_role_override.yml @@ -17,4 +17,4 @@ registry: server: registry.digitalocean.com username: user password: pw -primary_web_role: web_tokyo +primary_role: web_tokyo diff --git a/test/fixtures/deploy_workers_only.yml b/test/fixtures/deploy_workers_only.yml new file mode 100644 index 00000000..75cbbde1 --- /dev/null +++ b/test/fixtures/deploy_workers_only.yml @@ -0,0 +1,12 @@ +service: app +image: dhh/app +servers: + workers: + traefik: false + hosts: + - 1.1.1.1 + - 1.1.1.2 +primary_role: workers +registry: + username: user + password: pw