Skip to content

Commit

Permalink
Merge pull request #577 from basecamp/set-primary-web-role
Browse files Browse the repository at this point in the history
Support customizing the primary_web_role
  • Loading branch information
djmb authored Nov 13, 2023
2 parents 97ba6b7 + 073f745 commit 14a9129
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 4 deletions.
8 changes: 8 additions & 0 deletions lib/kamal/cli/templates/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,11 @@ registry:
# boot:
# 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
# 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
2 changes: 1 addition & 1 deletion lib/kamal/commands/healthcheck.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Kamal::Commands::Healthcheck < Kamal::Commands::Base

def run
web = config.role(:web)
web = config.role(config.primary_web_role)

docker :run,
"--detach",
Expand Down
24 changes: 21 additions & 3 deletions lib/kamal/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,20 @@ def all_hosts
end

def primary_web_host
role(:web).primary_host
role(primary_web_role)&.primary_host
end

def traefik_hosts
roles.select(&:running_traefik?).flat_map(&:hosts).uniq
def traefik_roles
roles.select(&:running_traefik?)
end

def traefik_role_names
traefik_roles.flat_map(&:name)
end

def traefik_hosts
traefik_roles.flat_map(&:hosts).uniq
end

def repository
[ raw_config.registry["server"], image ].compact.join("/")
Expand Down Expand Up @@ -199,6 +206,9 @@ def asset_path
raw_config.asset_path
end

def primary_web_role
raw_config.primary_web_role || "web"
end

def valid?
ensure_destination_if_required && ensure_required_keys_present && ensure_valid_kamal_version
Expand Down Expand Up @@ -253,6 +263,14 @@ def ensure_required_keys_present
end
end

unless role_names.include?(primary_web_role)
raise ArgumentError, "The primary_web_role #{primary_web_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

true
end

Expand Down
10 changes: 10 additions & 0 deletions test/cli/main_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,16 @@ class CliMainTest < CliTestCase
end
end

test "config with primary web role override" do
run_command("config", config_file: "deploy_primary_web_role_override").tap do |output|
config = YAML.load(output)

assert_equal ["web_chicago", "web_tokyo"], config[:roles]
assert_equal ["1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4"], config[:hosts]
assert_equal "1.1.1.3", config[:primary_host]
end
end

test "config with destination" do
run_command("config", "-d", "world", config_file: "deploy_for_dest").tap do |output|
config = YAML.load(output)
Expand Down
25 changes: 25 additions & 0 deletions test/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -278,4 +278,29 @@ class ConfigurationTest < ActiveSupport::TestCase
assert_nil @config.asset_path
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

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" } ))

assert_equal "alternate_web", config.primary_web_role
assert_equal "1.1.1.4", config.primary_web_host
end

test "primary web role no traefik" 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"))
end
assert_match /bar isn't defined/, error.message
end
end
20 changes: 20 additions & 0 deletions test/fixtures/deploy_primary_web_role_override.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
service: app
image: dhh/app
servers:
web_chicago:
traefik: enabled
hosts:
- 1.1.1.1
- 1.1.1.2
web_tokyo:
traefik: enabled
hosts:
- 1.1.1.3
- 1.1.1.4
env:
REDIS_URL: redis://x/y
registry:
server: registry.digitalocean.com
username: user
password: pw
primary_web_role: web_tokyo

0 comments on commit 14a9129

Please sign in to comment.