dash 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/kamal/cli/proxy/loadbalancer_reboot.rb +46 -0
- data/lib/kamal/cli/proxy/reboot.rb +1 -0
- data/lib/kamal/cli/proxy.rb +1 -8
- data/lib/kamal/commands/loadbalancer.rb +2 -2
- data/lib/kamal/commands/proxy.rb +6 -0
- data/lib/kamal/configuration/loadbalancer.rb +14 -2
- data/lib/kamal/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0c267bf789f49a3eede649d1b17a328fefe83367ae48ddde1ae45feec2185460
|
|
4
|
+
data.tar.gz: 16248804c04178338ca3a4187f5299135c6c25cd1f8691b16394e9b70f61f5ff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 12bf8d9a911c032b75256ef587f796503c062c9988c8fc6ae88448b019ecb3bcab0a06a3055a38a806fa56ca0ecc4cbafa2cdb105428b86a3084ae32972e6bd1
|
|
7
|
+
data.tar.gz: 89013ac78a74c960f6598517216fe536cc3eba9f237bde7f62af00c57eaed164c85c7584ca3aadbb0d566261b5a9cec429125ff39fd5de6792c515be5a8fb02a
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
# loadbalancer keeps its service state in the config volume, which the
|
|
7
7
|
# replacement container re-mounts, so every app's routes survive the gap.
|
|
8
8
|
class Kamal::Cli::Proxy::LoadbalancerReboot
|
|
9
|
+
READY_TIMEOUT = 30
|
|
10
|
+
|
|
9
11
|
attr_reader :host, :sshkit
|
|
10
12
|
delegate :execute, :capture_with_info, :info, :upload!, to: :sshkit
|
|
11
13
|
|
|
@@ -33,9 +35,53 @@ class Kamal::Cli::Proxy::LoadbalancerReboot
|
|
|
33
35
|
Kamal::Cli::Proxy::LoadbalancerClaim.new(host, sshkit).claim_run_config(replace: true)
|
|
34
36
|
execute *KAMAL.loadbalancer.run
|
|
35
37
|
|
|
38
|
+
wait_until_ready
|
|
39
|
+
verify_service if re_register_service
|
|
40
|
+
|
|
36
41
|
# kamal-proxy keeps its service state in the config volume, which the
|
|
37
42
|
# replacement container re-mounts - every app's routes survive.
|
|
38
43
|
services = capture_with_info(*KAMAL.loadbalancer.list).strip
|
|
39
44
|
info "Services registered on the load balancer at #{host} after reboot:\n#{services}"
|
|
40
45
|
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
def wait_until_ready
|
|
49
|
+
deadline = Time.now + READY_TIMEOUT
|
|
50
|
+
|
|
51
|
+
begin
|
|
52
|
+
capture_with_info(*KAMAL.loadbalancer.list, verbosity: :debug)
|
|
53
|
+
rescue SSHKit::Command::Failed
|
|
54
|
+
raise Kamal::Cli::BootError, "the load balancer on #{host} did not become ready within #{READY_TIMEOUT} seconds" if Time.now >= deadline
|
|
55
|
+
sleep 0.5
|
|
56
|
+
retry
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# A deploy failure after this reboot must not strand a fresh LB with no
|
|
61
|
+
# services: re-register this app's routes now rather than trusting the
|
|
62
|
+
# deploy step that hasn't run yet, mirroring the per-host proxy reboot.
|
|
63
|
+
#
|
|
64
|
+
# Only this app's registration can be rebuilt from this deploy.yml - the
|
|
65
|
+
# owner files of other apps sharing the LB record tokens, not deploy
|
|
66
|
+
# commands - so anything else rides on the state-volume restore (which
|
|
67
|
+
# --recheck-targets-on-restore re-verifies). No owner record, or a foreign
|
|
68
|
+
# one, means nothing of ours to restore.
|
|
69
|
+
def re_register_service
|
|
70
|
+
owner = capture_with_info(*KAMAL.loadbalancer.read_service_owner, raise_on_non_zero_exit: false).strip
|
|
71
|
+
return false unless owner == KAMAL.loadbalancer_config.owner_token
|
|
72
|
+
|
|
73
|
+
info "Re-registering #{KAMAL.config.service} with the load balancer on #{host}..."
|
|
74
|
+
execute *KAMAL.loadbalancer.deploy(targets: KAMAL.loadbalancer_config.target_hosts)
|
|
75
|
+
true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# `list --json` returns {"services": {"<name>": ...}} - exact key
|
|
79
|
+
# membership, same as the per-host proxy reboot's verification.
|
|
80
|
+
def verify_service
|
|
81
|
+
listed = JSON.parse(capture_with_info(*KAMAL.loadbalancer.list(json: true))).fetch("services", {}).keys
|
|
82
|
+
|
|
83
|
+
unless listed.include?(KAMAL.config.service)
|
|
84
|
+
raise Kamal::Cli::BootError, "the load balancer on #{host} is missing service #{KAMAL.config.service} after reboot"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
41
87
|
end
|
|
@@ -83,6 +83,7 @@ class Kamal::Cli::Proxy::Reboot
|
|
|
83
83
|
execute *proxy.run(digest: drift.expected_digest, name: proxy.next_container_name)
|
|
84
84
|
wait_until_ready(name: proxy.next_container_name)
|
|
85
85
|
|
|
86
|
+
execute *proxy.disable_restart
|
|
86
87
|
execute *proxy.drain(timeout: KAMAL.config.drain_timeout)
|
|
87
88
|
execute *proxy.wait_for_exit
|
|
88
89
|
execute *proxy.remove_stopped_container
|
data/lib/kamal/cli/proxy.rb
CHANGED
|
@@ -426,14 +426,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|
|
426
426
|
end
|
|
427
427
|
when "deploy"
|
|
428
428
|
if KAMAL.config.proxy.load_balancing?
|
|
429
|
-
targets =
|
|
430
|
-
KAMAL.config.roles.each do |role|
|
|
431
|
-
next unless role.running_proxy?
|
|
432
|
-
|
|
433
|
-
role.hosts.each do |host|
|
|
434
|
-
targets << host
|
|
435
|
-
end
|
|
436
|
-
end
|
|
429
|
+
targets = KAMAL.loadbalancer_config.target_hosts
|
|
437
430
|
|
|
438
431
|
on(KAMAL.config.proxy.effective_loadbalancer) do |host|
|
|
439
432
|
Kamal::Cli::Proxy::LoadbalancerClaim.new(host, self).claim_service
|
|
@@ -44,8 +44,8 @@ class Kamal::Commands::Loadbalancer < Kamal::Commands::Base
|
|
|
44
44
|
docker :exec, container_name, "kamal-proxy", "domains", subcommand
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
def list
|
|
48
|
-
docker :exec, container_name, "kamal-proxy", :list
|
|
47
|
+
def list(json: false)
|
|
48
|
+
docker :exec, container_name, "kamal-proxy", :list, *("--json" if json)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
# Cache policy is edge-only under load balancing (see the layering contract),
|
data/lib/kamal/commands/proxy.rb
CHANGED
|
@@ -113,6 +113,12 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base
|
|
|
113
113
|
container_id_for(container_name: proxy_run_config.holder_container_name, only_running: true)
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
+
# Cancel the restart policy before draining: drain makes the proxy exit on
|
|
117
|
+
# its own, which - unlike `docker stop` - an active restart policy would undo.
|
|
118
|
+
def disable_restart
|
|
119
|
+
docker :update, "--restart=no", container_name
|
|
120
|
+
end
|
|
121
|
+
|
|
116
122
|
def drain(timeout: nil)
|
|
117
123
|
docker :exec, container_name, "kamal-proxy", :drain, *("--drain-timeout=#{timeout}s" if timeout)
|
|
118
124
|
end
|
|
@@ -12,12 +12,24 @@ class Kamal::Configuration::Loadbalancer < Kamal::Configuration::Proxy
|
|
|
12
12
|
|
|
13
13
|
# The load balancer fans a single service out to many targets, so unlike the
|
|
14
14
|
# per-app proxy deploy (which takes one target) it takes the full list and
|
|
15
|
-
# joins them into a single --target flag
|
|
15
|
+
# joins them into a single --target flag.
|
|
16
|
+
#
|
|
17
|
+
# Each target is a per-host proxy, reached on its published HTTP port
|
|
18
|
+
# (run.http_port, default 80) - the only cross-host surface it exposes.
|
|
19
|
+
# Never app_port: that is how a per-host proxy reaches the app container
|
|
20
|
+
# inside its own docker network, and nothing listens on it across hosts.
|
|
16
21
|
def deploy_command_args(targets:)
|
|
17
|
-
target_arg = targets.map { |target| "#{target}:#{
|
|
22
|
+
target_arg = targets.map { |target| "#{target}:#{run.http_port}" }.join(",")
|
|
18
23
|
optionize ({ target: target_arg }).merge(deploy_options), with: "="
|
|
19
24
|
end
|
|
20
25
|
|
|
26
|
+
# The hosts the load balancer forwards to: every host of every role that
|
|
27
|
+
# runs a proxy. One source of truth for the deploy step and the reboot
|
|
28
|
+
# re-registration, so their target lists cannot diverge.
|
|
29
|
+
def target_hosts
|
|
30
|
+
config.roles.select(&:running_proxy?).flat_map(&:hosts)
|
|
31
|
+
end
|
|
32
|
+
|
|
21
33
|
def directory
|
|
22
34
|
File.join config.run_directory, "loadbalancer"
|
|
23
35
|
end
|
data/lib/kamal/version.rb
CHANGED