Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22e7243b10 | ||
|
|
259a018d5a | ||
|
|
a82e88d5c9 | ||
|
|
d6459e869a | ||
|
|
ad21c7e984 | ||
|
|
87965281a3 | ||
|
|
dca96eafaa | ||
|
|
7b1439c3c6 | ||
|
|
b9e5ce7ca7 | ||
|
|
f62c1a50c4 | ||
|
|
2c1d6ed891 |
@@ -1,7 +1,7 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
kamal (2.6.0)
|
||||
kamal (2.6.1)
|
||||
activesupport (>= 7.0)
|
||||
base64 (~> 0.2)
|
||||
bcrypt_pbkdf (~> 1.0)
|
||||
|
||||
@@ -14,6 +14,10 @@ class Kamal::Cli::Build < Kamal::Cli::Base
|
||||
def push
|
||||
cli = self
|
||||
|
||||
# Ensure pre-connect hooks run before the build, they may needed for a remote builder
|
||||
# or the pre-build hooks.
|
||||
pre_connect_if_required
|
||||
|
||||
ensure_docker_installed
|
||||
login_to_registry_locally
|
||||
|
||||
|
||||
@@ -120,18 +120,6 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
||||
execute *KAMAL.proxy.ensure_apps_config_directory
|
||||
|
||||
execute *KAMAL.proxy.run
|
||||
|
||||
KAMAL.roles_on(host).select(&:running_proxy?).each do |role|
|
||||
app = KAMAL.app(role: role, host: host)
|
||||
|
||||
version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip
|
||||
endpoint = capture_with_info(*app.container_id_for_version(version)).strip
|
||||
|
||||
if endpoint.present?
|
||||
info "Deploying #{endpoint} for role `#{role}` on #{host}..."
|
||||
execute *app.deploy(target: endpoint)
|
||||
end
|
||||
end
|
||||
end
|
||||
run_hook "post-proxy-reboot", hosts: host_list
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ class Kamal::Commander::Specifics
|
||||
@primary_role = primary_or_first_role(roles_on(primary_host))
|
||||
|
||||
stable_sort!(roles) { |role| role == primary_role ? 0 : 1 }
|
||||
stable_sort!(hosts) { |host| roles_on(host).any? { |role| role == primary_role } ? 0 : 1 }
|
||||
sort_primary_role_hosts_first!(hosts)
|
||||
end
|
||||
|
||||
def roles_on(host)
|
||||
@@ -19,7 +19,7 @@ class Kamal::Commander::Specifics
|
||||
end
|
||||
|
||||
def app_hosts
|
||||
config.app_hosts & specified_hosts
|
||||
@app_hosts ||= sort_primary_role_hosts_first!(config.app_hosts & specified_hosts)
|
||||
end
|
||||
|
||||
def proxy_hosts
|
||||
@@ -55,4 +55,8 @@ class Kamal::Commander::Specifics
|
||||
specified_hosts
|
||||
end
|
||||
end
|
||||
|
||||
def sort_primary_role_hosts_first!(hosts)
|
||||
stable_sort!(hosts) { |host| roles_on(host).any? { |role| role == primary_role } ? 0 : 1 }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -63,7 +63,7 @@ class Kamal::Configuration
|
||||
@env = Env.new(config: @raw_config.env || {}, secrets: secrets)
|
||||
|
||||
@logging = Logging.new(logging_config: @raw_config.logging)
|
||||
@proxy = Proxy.new(config: self, proxy_config: @raw_config.key?(:proxy) ? @raw_config.proxy : {})
|
||||
@proxy = Proxy.new(config: self, proxy_config: @raw_config.proxy)
|
||||
@proxy_boot = Proxy::Boot.new(config: self)
|
||||
@ssh = Ssh.new(config: self)
|
||||
@sshkit = Sshkit.new(config: self)
|
||||
|
||||
@@ -10,11 +10,6 @@
|
||||
# They are application-specific, so they are not shared when multiple applications
|
||||
# run on the same proxy.
|
||||
#
|
||||
# The proxy is enabled by default on the primary role but can be disabled by
|
||||
# setting `proxy: false`.
|
||||
#
|
||||
# It is disabled by default on all other roles but can be enabled by setting
|
||||
# `proxy: true` or providing a proxy configuration.
|
||||
proxy:
|
||||
|
||||
# Hosts
|
||||
@@ -113,3 +108,30 @@ proxy:
|
||||
response_headers:
|
||||
- X-Request-ID
|
||||
- X-Request-Start
|
||||
|
||||
# Enabling/disabling the proxy on roles
|
||||
#
|
||||
# The proxy is enabled by default on the primary role but can be disabled by
|
||||
# setting `proxy: false` in the primary role's configuration.
|
||||
#
|
||||
# ```yaml
|
||||
# servers:
|
||||
# web:
|
||||
# hosts:
|
||||
# - ...
|
||||
# proxy: false
|
||||
# ```
|
||||
#
|
||||
# It is disabled by default on all other roles but can be enabled by setting
|
||||
# `proxy: true` or providing a proxy configuration for that role.
|
||||
#
|
||||
# ```yaml
|
||||
# servers:
|
||||
# web:
|
||||
# hosts:
|
||||
# - ...
|
||||
# web2:
|
||||
# hosts:
|
||||
# - ...
|
||||
# proxy: true
|
||||
# ```
|
||||
|
||||
@@ -11,6 +11,7 @@ class Kamal::Configuration::Proxy
|
||||
def initialize(config:, proxy_config:, context: "proxy")
|
||||
@config = config
|
||||
@proxy_config = proxy_config
|
||||
@proxy_config = {} if @proxy_config.nil?
|
||||
validate! @proxy_config, with: Kamal::Configuration::Validator::Proxy, context: context
|
||||
end
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module Kamal
|
||||
VERSION = "2.6.0"
|
||||
VERSION = "2.6.1"
|
||||
end
|
||||
|
||||
@@ -21,6 +21,7 @@ class CliBuildTest < CliTestCase
|
||||
.returns("")
|
||||
|
||||
run_command("push", "--verbose").tap do |output|
|
||||
assert_hook_ran "pre-connect", output
|
||||
assert_hook_ran "pre-build", output
|
||||
assert_match /Cloning repo into build directory/, output
|
||||
assert_match /git -C #{Dir.tmpdir}\/kamal-clones\/app-#{pwd_sha} clone #{Dir.pwd}/, output
|
||||
|
||||
@@ -44,42 +44,20 @@ class CliProxyTest < CliTestCase
|
||||
end
|
||||
|
||||
test "reboot" do
|
||||
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
|
||||
.with(:docker, :container, :ls, "--all", "--filter", "name=^app-web-123$", "--quiet")
|
||||
.returns("abcdefabcdef")
|
||||
.at_least_once
|
||||
|
||||
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
|
||||
.with { |*args| args[0..1] == [ :sh, "-c" ] }
|
||||
.returns("123")
|
||||
.at_least_once
|
||||
|
||||
run_command("reboot", "-y").tap do |output|
|
||||
assert_match "docker container stop kamal-proxy on 1.1.1.1", output
|
||||
assert_match "docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy on 1.1.1.1", output
|
||||
assert_match "mkdir -p .kamal/proxy/apps-config on 1.1.1.1", output
|
||||
assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") $(cat .kamal/proxy/run_command 2> /dev/null || echo \"\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config on 1.1.1.1", output
|
||||
assert_match "docker exec kamal-proxy kamal-proxy deploy app-web --target=\"abcdefabcdef:80\" --deploy-timeout=\"6s\" --drain-timeout=\"30s\" --buffer-requests --buffer-responses --log-request-header=\"Cache-Control\" --log-request-header=\"Last-Modified\" --log-request-header=\"User-Agent\" on 1.1.1.1", output
|
||||
|
||||
assert_match "docker container stop kamal-proxy on 1.1.1.2", output
|
||||
assert_match "docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy on 1.1.1.2", output
|
||||
assert_match "mkdir -p .kamal/proxy/apps-config on 1.1.1.1", output
|
||||
assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") $(cat .kamal/proxy/image 2> /dev/null || echo \"basecamp/kamal-proxy\"):$(cat .kamal/proxy/image_version 2> /dev/null || echo \"#{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}\") $(cat .kamal/proxy/run_command 2> /dev/null || echo \"\") | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy --volume $(pwd)/.kamal/proxy/apps-config:/home/kamal-proxy/.apps-config on 1.1.1.2", output
|
||||
assert_match "docker exec kamal-proxy kamal-proxy deploy app-web --target=\"abcdefabcdef:80\" --deploy-timeout=\"6s\" --drain-timeout=\"30s\" --buffer-requests --buffer-responses --log-request-header=\"Cache-Control\" --log-request-header=\"Last-Modified\" --log-request-header=\"User-Agent\" on 1.1.1.2", output
|
||||
end
|
||||
end
|
||||
|
||||
test "reboot --rolling" do
|
||||
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
|
||||
.with(:docker, :container, :ls, "--all", "--filter", "name=^app-web-123$", "--quiet")
|
||||
.returns("abcdefabcdef")
|
||||
.at_least_once
|
||||
|
||||
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
|
||||
.with { |*args| args[0..1] == [ :sh, "-c" ] }
|
||||
.returns("123")
|
||||
.at_least_once
|
||||
|
||||
run_command("reboot", "--rolling", "-y").tap do |output|
|
||||
assert_match "Running docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy on 1.1.1.1", output
|
||||
end
|
||||
|
||||
@@ -149,6 +149,12 @@ class CommanderTest < ActiveSupport::TestCase
|
||||
assert_equal [], @kamal.accessory_hosts
|
||||
end
|
||||
|
||||
test "primary role hosts are first" do
|
||||
configure_with(:deploy_with_roles_workers_primary)
|
||||
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" ], @kamal.hosts
|
||||
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" ], @kamal.app_hosts
|
||||
end
|
||||
|
||||
private
|
||||
def configure_with(variant)
|
||||
@kamal = Kamal::Commander.new.tap do |kamal|
|
||||
|
||||
19
test/fixtures/deploy_with_roles_workers_primary.yml
vendored
Normal file
19
test/fixtures/deploy_with_roles_workers_primary.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
service: app
|
||||
image: dhh/app
|
||||
servers:
|
||||
workers:
|
||||
- 1.1.1.1
|
||||
- 1.1.1.2
|
||||
web:
|
||||
- 1.1.1.3
|
||||
- 1.1.1.4
|
||||
env:
|
||||
REDIS_URL: redis://x/y
|
||||
registry:
|
||||
server: registry.digitalocean.com
|
||||
username: user
|
||||
password: pw
|
||||
builder:
|
||||
arch: amd64
|
||||
deploy_timeout: 1
|
||||
primary_role: workers
|
||||
Reference in New Issue
Block a user