Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support customizing the primary_web_role #577

Merged
merged 6 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading