dash 3.2.0 → 3.2.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/README.md +1 -1
- data/bin/dash +2 -2
- data/lib/{kamal → dash}/cli/accessory.rb +24 -24
- data/lib/dash/cli/alias/command.rb +10 -0
- data/lib/{kamal → dash}/cli/app/assets.rb +2 -2
- data/lib/{kamal → dash}/cli/app/boot.rb +15 -15
- data/lib/{kamal → dash}/cli/app/error_pages.rb +6 -6
- data/lib/{kamal → dash}/cli/app/rollout_boot.rb +6 -6
- data/lib/{kamal → dash}/cli/app/ssl_certificates.rb +3 -3
- data/lib/{kamal → dash}/cli/app.rb +86 -86
- data/lib/{kamal → dash}/cli/base.rb +71 -47
- data/lib/dash/cli/build/clone.rb +59 -0
- data/lib/{kamal → dash}/cli/build/port_forwarding.rb +1 -1
- data/lib/{kamal → dash}/cli/build.rb +45 -45
- data/lib/{kamal → dash}/cli/doctor/config_checks.rb +3 -3
- data/lib/{kamal → dash}/cli/doctor/endpoint_checks.rb +25 -7
- data/lib/{kamal → dash}/cli/doctor/host_checks.rb +18 -18
- data/lib/{kamal → dash}/cli/doctor.rb +9 -9
- data/lib/{kamal → dash}/cli/healthcheck/barrier.rb +2 -2
- data/lib/{kamal → dash}/cli/healthcheck/drift_error.rb +2 -2
- data/lib/dash/cli/healthcheck/error.rb +2 -0
- data/lib/{kamal → dash}/cli/healthcheck/poller.rb +7 -7
- data/lib/{kamal → dash}/cli/lock.rb +1 -1
- data/lib/dash/cli/main/migrate.rb +77 -0
- data/lib/{kamal → dash}/cli/main.rb +77 -66
- data/lib/{kamal → dash}/cli/proxy/drift.rb +3 -3
- data/lib/{kamal → dash}/cli/proxy/loadbalancer_claim.rb +3 -3
- data/lib/{kamal → dash}/cli/proxy/loadbalancer_reboot.rb +22 -22
- data/lib/{kamal → dash}/cli/proxy/reboot.rb +15 -15
- data/lib/{kamal → dash}/cli/proxy.rb +166 -154
- data/lib/{kamal → dash}/cli/prune.rb +10 -10
- data/lib/{kamal → dash}/cli/registry.rb +11 -11
- data/lib/{kamal → dash}/cli/secrets.rb +3 -3
- data/lib/{kamal → dash}/cli/server.rb +14 -14
- data/lib/{kamal → dash}/cli/templates/deploy.yml +4 -4
- data/lib/dash/cli/templates/sample_hooks/docker-setup.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/post-app-boot.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/post-app-stop.sample +9 -0
- data/lib/dash/cli/templates/sample_hooks/post-deploy.sample +14 -0
- data/lib/dash/cli/templates/sample_hooks/post-proxy-deploy.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/pre-app-boot.sample +3 -0
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-app-stop.sample +2 -2
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-build.sample +8 -8
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-connect.sample +8 -8
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-deploy.sample +9 -9
- data/lib/dash/cli/templates/sample_hooks/pre-proxy-deploy.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/pre-proxy-reboot.sample +3 -0
- data/lib/{kamal → dash}/cli/templates/secrets +6 -6
- data/lib/{kamal → dash}/cli.rb +2 -2
- data/lib/{kamal → dash}/commander/specifics.rb +2 -2
- data/lib/{kamal → dash}/commander.rb +31 -23
- data/lib/{kamal → dash}/commands/accessory/proxy.rb +1 -1
- data/lib/{kamal → dash}/commands/accessory.rb +2 -2
- data/lib/{kamal → dash}/commands/app/assets.rb +1 -1
- data/lib/{kamal → dash}/commands/app/containers.rb +1 -1
- data/lib/{kamal → dash}/commands/app/error_pages.rb +2 -2
- data/lib/{kamal → dash}/commands/app/execution.rb +1 -1
- data/lib/{kamal → dash}/commands/app/images.rb +1 -1
- data/lib/{kamal → dash}/commands/app/logging.rb +1 -1
- data/lib/{kamal → dash}/commands/app/proxy.rb +1 -1
- data/lib/{kamal → dash}/commands/app.rb +1 -1
- data/lib/{kamal → dash}/commands/auditor.rb +3 -7
- data/lib/{kamal → dash}/commands/base.rb +39 -3
- data/lib/{kamal → dash}/commands/builder/base.rb +2 -2
- data/lib/{kamal → dash}/commands/builder/clone.rb +3 -3
- data/lib/{kamal → dash}/commands/builder/cloud.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/hybrid.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/local.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/pack.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/remote.rb +1 -1
- data/lib/{kamal → dash}/commands/builder.rb +7 -7
- data/lib/{kamal → dash}/commands/docker.rb +1 -1
- data/lib/{kamal → dash}/commands/hook.rb +1 -1
- data/lib/{kamal → dash}/commands/loadbalancer.rb +9 -8
- data/lib/{kamal → dash}/commands/lock.rb +2 -2
- data/lib/{kamal → dash}/commands/proxy/cert_transfer.rb +2 -2
- data/lib/{kamal → dash}/commands/proxy.rb +20 -10
- data/lib/{kamal → dash}/commands/prune.rb +1 -1
- data/lib/dash/commands/registry.rb +44 -0
- data/lib/{kamal → dash}/commands/server.rb +1 -5
- data/lib/dash/commands.rb +2 -0
- data/lib/{kamal → dash}/configuration/accessory.rb +11 -11
- data/lib/{kamal → dash}/configuration/alias.rb +3 -3
- data/lib/{kamal → dash}/configuration/boot.rb +2 -2
- data/lib/{kamal → dash}/configuration/builder.rb +7 -7
- data/lib/{kamal → dash}/configuration/docs/builder.yml +3 -3
- data/lib/{kamal → dash}/configuration/docs/configuration.yml +12 -5
- data/lib/{kamal → dash}/configuration/docs/env.yml +10 -10
- data/lib/{kamal → dash}/configuration/docs/proxy.yml +31 -8
- data/lib/{kamal → dash}/configuration/docs/registry.yml +5 -5
- data/lib/{kamal → dash}/configuration/env/tag.rb +2 -2
- data/lib/{kamal → dash}/configuration/env.rb +5 -5
- data/lib/{kamal → dash}/configuration/loadbalancer.rb +3 -3
- data/lib/{kamal → dash}/configuration/logging.rb +3 -3
- data/lib/{kamal → dash}/configuration/output.rb +4 -4
- data/lib/{kamal → dash}/configuration/proxy/acme.rb +4 -3
- data/lib/{kamal → dash}/configuration/proxy/boot.rb +7 -7
- data/lib/{kamal → dash}/configuration/proxy/run.rb +11 -11
- data/lib/{kamal → dash}/configuration/proxy.rb +15 -15
- data/lib/{kamal → dash}/configuration/registry.rb +3 -3
- data/lib/{kamal → dash}/configuration/role/healthcheck.rb +3 -3
- data/lib/{kamal → dash}/configuration/role.rb +12 -12
- data/lib/{kamal → dash}/configuration/servers.rb +4 -4
- data/lib/{kamal → dash}/configuration/ssh.rb +2 -2
- data/lib/{kamal → dash}/configuration/sshkit.rb +2 -2
- data/lib/{kamal → dash}/configuration/validation.rb +2 -2
- data/lib/{kamal → dash}/configuration/validator/accessory.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator/alias.rb +2 -2
- data/lib/{kamal → dash}/configuration/validator/builder.rb +1 -1
- data/lib/dash/configuration/validator/configuration.rb +6 -0
- data/lib/{kamal → dash}/configuration/validator/env.rb +2 -2
- data/lib/{kamal → dash}/configuration/validator/proxy.rb +8 -8
- data/lib/{kamal → dash}/configuration/validator/registry.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator/role.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator/servers.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator.rb +4 -4
- data/lib/{kamal → dash}/configuration/volume.rb +2 -2
- data/lib/{kamal → dash}/configuration.rb +39 -29
- data/lib/{kamal → dash}/docker.rb +1 -1
- data/lib/{kamal → dash}/env_file.rb +1 -1
- data/lib/{kamal → dash}/git.rb +1 -1
- data/lib/{kamal → dash}/otel_shipper.rb +3 -3
- data/lib/{kamal → dash}/output/base_logger.rb +1 -1
- data/lib/{kamal → dash}/output/file_logger.rb +1 -1
- data/lib/{kamal → dash}/output/formatter.rb +1 -1
- data/lib/{kamal → dash}/output/otel_logger.rb +3 -3
- data/lib/dash/project_directory.rb +28 -0
- data/lib/{kamal → dash}/secrets/adapters/aws_secrets_manager.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/base.rb +2 -2
- data/lib/{kamal → dash}/secrets/adapters/bitwarden.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/bitwarden_secrets_manager.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/doppler.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/enpass.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/gcp_secret_manager.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/last_pass.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/one_password.rb +2 -2
- data/lib/{kamal → dash}/secrets/adapters/passbolt.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/test.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters.rb +2 -2
- data/lib/{kamal → dash}/secrets/dotenv/inline_command_substitution.rb +2 -2
- data/lib/{kamal → dash}/secrets.rb +6 -6
- data/lib/{kamal → dash}/tags.rb +8 -3
- data/lib/{kamal → dash}/utils/sensitive.rb +1 -1
- data/lib/{kamal → dash}/utils.rb +15 -5
- data/lib/dash/version.rb +3 -0
- data/lib/{kamal.rb → dash.rb} +4 -4
- metadata +156 -154
- data/lib/kamal/cli/alias/command.rb +0 -10
- data/lib/kamal/cli/build/clone.rb +0 -59
- data/lib/kamal/cli/healthcheck/error.rb +0 -2
- data/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/post-app-boot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/post-app-stop.sample +0 -9
- data/lib/kamal/cli/templates/sample_hooks/post-deploy.sample +0 -14
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-deploy.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-app-boot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-proxy-deploy.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-proxy-reboot.sample +0 -3
- data/lib/kamal/commands/registry.rb +0 -38
- data/lib/kamal/commands.rb +0 -2
- data/lib/kamal/configuration/validator/configuration.rb +0 -6
- data/lib/kamal/version.rb +0 -3
- /data/lib/{kamal → dash}/configuration/docs/accessory.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/alias.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/boot.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/logging.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/output.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/role.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/servers.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/ssh.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/sshkit.yml +0 -0
- /data/lib/{kamal → dash}/sshkit_with_ext.rb +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c3a110ddc9f31ad566bce549f84ef6b216a395d9201e02747f1e062d89406f07
|
|
4
|
+
data.tar.gz: 40fcfdf62082cf07a8e7e19455fd9398567e6ace96be7426165d27309f0ef29e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c9a19af8c3f5c210d01d8aa9dcdee7e2ad76018050cf7df70ca3bc04a85089702a8ec32b14eab38701e48ffa2306880333e5fd2309e109fb83b720ea27041f33
|
|
7
|
+
data.tar.gz: bf7739b92e6685eb9bc62453eed18c7ba127faf29d42c15023b890632b4c2f3b8e1481e9fc3481b189b27a86dd39c04a57d08d5c00b46fe89b2a294ed807144e
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
From bare metal to cloud VMs, deploy web apps anywhere with zero downtime. dash uses [dash-proxy](https://github.com/zoolutions/dash-proxy) to seamlessly switch requests between containers, load-balance across multiple hosts, batch SAN certificates, and issue wildcard certs via DNS-01. Works across multiple servers, using SSHKit to execute commands. Originally built for Rails apps, dash works with any type of web app that can be containerized with Docker.
|
|
4
4
|
|
|
5
|
-
dash began as a fork of [basecamp/kamal](https://github.com/basecamp/kamal) and made a clean break in 2026 — it ships the features upstream wouldn't merge (proxy load balancing, readiness gates, response caching, traffic shaping, and more) and moves at its own pace. Existing kamal deployments upgrade in place: the on-server artifacts (`.kamal/` directory, `kamal-proxy` container, `KAMAL_*`
|
|
5
|
+
dash began as a fork of [basecamp/kamal](https://github.com/basecamp/kamal) and made a clean break in 2026 — it ships the features upstream wouldn't merge (proxy load balancing, readiness gates, response caching, traffic shaping, and more) and moves at its own pace. Existing kamal deployments upgrade in place: the on-server artifacts (`.kamal/` directory, `kamal-proxy` container) are unchanged, `KAMAL_*` env vars are still set alongside their `DASH_*` twins, and a `.kamal/` directory in your own repo is still read — `dash migrate` moves it to `.dash/` when you're ready.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
data/bin/dash
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
# Prevent failures from being reported twice.
|
|
4
4
|
Thread.report_on_exception = false
|
|
5
5
|
|
|
6
|
-
require "
|
|
6
|
+
require "dash"
|
|
7
7
|
|
|
8
8
|
begin
|
|
9
|
-
|
|
9
|
+
Dash::Cli::Main.start(ARGV)
|
|
10
10
|
rescue SSHKit::Runner::ExecuteError => e
|
|
11
11
|
puts " \e[31mERROR (#{e.cause.class}): #{e.message}\e[0m"
|
|
12
12
|
puts e.cause.backtrace if ENV["VERBOSE"]
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
require "active_support/core_ext/array/conversions"
|
|
2
2
|
require "concurrent/array"
|
|
3
3
|
|
|
4
|
-
class
|
|
4
|
+
class Dash::Cli::Accessory < Dash::Cli::Base
|
|
5
5
|
desc "boot [NAME]", "Boot new accessory service on host (use NAME=all to boot all accessories)"
|
|
6
6
|
def boot(name, prepare: true)
|
|
7
7
|
modify(lock: true) do
|
|
8
8
|
if name == "all"
|
|
9
|
-
|
|
9
|
+
DASH.accessory_names.each { |accessory_name| boot(accessory_name) }
|
|
10
10
|
else
|
|
11
11
|
prepare(name) if prepare
|
|
12
12
|
|
|
@@ -25,7 +25,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
25
25
|
upload(name)
|
|
26
26
|
|
|
27
27
|
on(hosts) do |host|
|
|
28
|
-
execute *
|
|
28
|
+
execute *DASH.auditor.record("Booted #{name} accessory"), verbosity: :debug
|
|
29
29
|
execute *accessory.ensure_env_directory
|
|
30
30
|
upload! accessory.secrets_io, accessory.secrets_path, mode: "0600"
|
|
31
31
|
execute *accessory.run(host: host)
|
|
@@ -78,7 +78,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
78
78
|
def reboot(name)
|
|
79
79
|
modify(lock: true) do
|
|
80
80
|
if name == "all"
|
|
81
|
-
|
|
81
|
+
DASH.accessory_names.each { |accessory_name| reboot(accessory_name) }
|
|
82
82
|
else
|
|
83
83
|
prepare(name)
|
|
84
84
|
pull_image(name)
|
|
@@ -94,7 +94,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
94
94
|
modify(lock: true) do
|
|
95
95
|
with_accessory(name) do |accessory, hosts|
|
|
96
96
|
on(hosts) do
|
|
97
|
-
execute *
|
|
97
|
+
execute *DASH.auditor.record("Started #{name} accessory"), verbosity: :debug
|
|
98
98
|
execute *accessory.start
|
|
99
99
|
if accessory.running_proxy?
|
|
100
100
|
target = capture_with_info(*accessory.container_id_for(container_name: accessory.service_name, only_running: true)).strip
|
|
@@ -110,7 +110,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
110
110
|
modify(lock: true) do
|
|
111
111
|
with_accessory(name) do |accessory, hosts|
|
|
112
112
|
on(hosts) do
|
|
113
|
-
execute *
|
|
113
|
+
execute *DASH.auditor.record("Stopped #{name} accessory"), verbosity: :debug
|
|
114
114
|
execute *accessory.stop, raise_on_non_zero_exit: false
|
|
115
115
|
|
|
116
116
|
if accessory.running_proxy?
|
|
@@ -134,7 +134,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
134
134
|
def details(name)
|
|
135
135
|
quiet = options[:quiet]
|
|
136
136
|
if name == "all"
|
|
137
|
-
|
|
137
|
+
DASH.accessory_names.each { |accessory_name| details(accessory_name) }
|
|
138
138
|
else
|
|
139
139
|
type = "Accessory #{name}"
|
|
140
140
|
with_accessory(name) do |accessory, hosts|
|
|
@@ -157,7 +157,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
157
157
|
with_raw_output(raw) do
|
|
158
158
|
pre_connect_if_required
|
|
159
159
|
|
|
160
|
-
cmd =
|
|
160
|
+
cmd = Dash::Utils.join_commands(cmd)
|
|
161
161
|
quiet = options[:quiet]
|
|
162
162
|
|
|
163
163
|
with_accessory(name) do |accessory, hosts|
|
|
@@ -168,21 +168,21 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
168
168
|
|
|
169
169
|
when options[:interactive]
|
|
170
170
|
say "Launching interactive command via SSH from new container...", :magenta
|
|
171
|
-
on(accessory.hosts.first) { execute *
|
|
171
|
+
on(accessory.hosts.first) { execute *DASH.registry.login }
|
|
172
172
|
run_locally { exec accessory.execute_in_new_container_over_ssh(cmd) }
|
|
173
173
|
|
|
174
174
|
when options[:reuse]
|
|
175
175
|
say "Launching command from existing container...", :magenta
|
|
176
176
|
on(hosts) do |host|
|
|
177
|
-
execute *
|
|
177
|
+
execute *DASH.auditor.record("Executed cmd '#{cmd}' on #{name} accessory"), verbosity: :debug
|
|
178
178
|
puts_by_host host, capture_with_info(*accessory.execute_in_existing_container(cmd), strip: !raw), quiet: quiet, raw: raw
|
|
179
179
|
end
|
|
180
180
|
|
|
181
181
|
else
|
|
182
182
|
say "Launching command from new container...", :magenta
|
|
183
183
|
on(hosts) do |host|
|
|
184
|
-
execute *
|
|
185
|
-
execute *
|
|
184
|
+
execute *DASH.registry.login
|
|
185
|
+
execute *DASH.auditor.record("Executed cmd '#{cmd}' on #{name} accessory"), verbosity: :debug
|
|
186
186
|
puts_by_host host, capture_with_info(*accessory.execute_in_new_container(cmd), strip: !raw), quiet: quiet, raw: raw
|
|
187
187
|
end
|
|
188
188
|
end
|
|
@@ -225,7 +225,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
225
225
|
modify(lock: true) do
|
|
226
226
|
with_accessory(name) do |accessory, hosts|
|
|
227
227
|
on(hosts) do
|
|
228
|
-
execute *
|
|
228
|
+
execute *DASH.auditor.record("Pull #{name} accessory image"), verbosity: :debug
|
|
229
229
|
execute *accessory.pull_image
|
|
230
230
|
end
|
|
231
231
|
end
|
|
@@ -238,7 +238,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
238
238
|
confirming "This will remove all containers, images and data directories for #{name}. Are you sure?" do
|
|
239
239
|
modify(lock: true) do
|
|
240
240
|
if name == "all"
|
|
241
|
-
|
|
241
|
+
DASH.accessory_names.each { |accessory_name| remove_accessory(accessory_name) }
|
|
242
242
|
else
|
|
243
243
|
remove_accessory(name)
|
|
244
244
|
end
|
|
@@ -251,7 +251,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
251
251
|
modify(lock: true) do
|
|
252
252
|
with_accessory(name) do |accessory, hosts|
|
|
253
253
|
on(hosts) do
|
|
254
|
-
execute *
|
|
254
|
+
execute *DASH.auditor.record("Remove #{name} accessory container"), verbosity: :debug
|
|
255
255
|
execute *accessory.remove_container
|
|
256
256
|
end
|
|
257
257
|
end
|
|
@@ -263,7 +263,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
263
263
|
modify(lock: true) do
|
|
264
264
|
with_accessory(name) do |accessory, hosts|
|
|
265
265
|
on(hosts) do
|
|
266
|
-
execute *
|
|
266
|
+
execute *DASH.auditor.record("Removed #{name} accessory image"), verbosity: :debug
|
|
267
267
|
execute *accessory.remove_image
|
|
268
268
|
end
|
|
269
269
|
end
|
|
@@ -287,10 +287,10 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
287
287
|
def upgrade(name)
|
|
288
288
|
confirming "This will restart all accessories" do
|
|
289
289
|
modify(lock: true) do
|
|
290
|
-
host_groups = options[:rolling] ?
|
|
290
|
+
host_groups = options[:rolling] ? DASH.accessory_hosts : [ DASH.accessory_hosts ]
|
|
291
291
|
host_groups.each do |hosts|
|
|
292
292
|
host_list = Array(hosts).join(",")
|
|
293
|
-
|
|
293
|
+
DASH.with_specific_hosts(hosts) do
|
|
294
294
|
say "Upgrading #{name} accessories on #{host_list}...", :magenta
|
|
295
295
|
reboot name
|
|
296
296
|
say "Upgraded #{name} accessories on #{host_list}...", :magenta
|
|
@@ -302,8 +302,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
302
302
|
|
|
303
303
|
private
|
|
304
304
|
def with_accessory(name)
|
|
305
|
-
if
|
|
306
|
-
accessory =
|
|
305
|
+
if DASH.config.accessory(name)
|
|
306
|
+
accessory = DASH.accessory(name)
|
|
307
307
|
yield accessory, accessory_hosts(accessory)
|
|
308
308
|
else
|
|
309
309
|
error_on_missing_accessory(name)
|
|
@@ -311,7 +311,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
311
311
|
end
|
|
312
312
|
|
|
313
313
|
def error_on_missing_accessory(name)
|
|
314
|
-
options =
|
|
314
|
+
options = DASH.accessory_names.presence
|
|
315
315
|
|
|
316
316
|
error \
|
|
317
317
|
"No accessory by the name of '#{name}'" +
|
|
@@ -319,7 +319,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
319
319
|
end
|
|
320
320
|
|
|
321
321
|
def accessory_hosts(accessory)
|
|
322
|
-
|
|
322
|
+
DASH.accessory_hosts & accessory.hosts
|
|
323
323
|
end
|
|
324
324
|
|
|
325
325
|
def remove_accessory(name)
|
|
@@ -332,8 +332,8 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
|
332
332
|
def prepare(name)
|
|
333
333
|
with_accessory(name) do |accessory, hosts|
|
|
334
334
|
on(hosts) do
|
|
335
|
-
execute *
|
|
336
|
-
execute *
|
|
335
|
+
execute *DASH.registry.login(registry_config: accessory.registry)
|
|
336
|
+
execute *DASH.docker.create_network
|
|
337
337
|
rescue SSHKit::Command::Failed => e
|
|
338
338
|
raise unless e.message.include?("already exists")
|
|
339
339
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Cli::App::Assets
|
|
2
2
|
attr_reader :host, :role, :sshkit
|
|
3
3
|
delegate :execute, :capture_with_info, :info, to: :sshkit
|
|
4
4
|
delegate :assets?, to: :role
|
|
@@ -19,6 +19,6 @@ class Kamal::Cli::App::Assets
|
|
|
19
19
|
|
|
20
20
|
private
|
|
21
21
|
def app
|
|
22
|
-
@app ||=
|
|
22
|
+
@app ||= DASH.app(role: role, host: host)
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Cli::App::Boot
|
|
2
2
|
attr_reader :host, :role, :version, :barrier, :sshkit, :cli
|
|
3
3
|
delegate :execute, :capture_with_info, :capture_with_pretty_json, :info, :error, :upload!, to: :sshkit
|
|
4
4
|
delegate :run_hook, to: :cli
|
|
@@ -55,14 +55,14 @@ class Kamal::Cli::App::Boot
|
|
|
55
55
|
execute *app.run(hostname: hostname)
|
|
56
56
|
if running_proxy?
|
|
57
57
|
endpoint = capture_with_info(*app.container_id_for_version(version)).strip
|
|
58
|
-
raise
|
|
58
|
+
raise Dash::Cli::BootError, "Failed to get endpoint for #{role} on #{host}, did the container boot?" if endpoint.empty?
|
|
59
59
|
|
|
60
60
|
run_hook "pre-proxy-deploy", hosts: host.to_s, role: role.name
|
|
61
|
-
info "Deploying #{role} on #{host} via kamal-proxy (waiting up to #{
|
|
61
|
+
info "Deploying #{role} on #{host} via kamal-proxy (waiting up to #{DASH.config.deploy_timeout}s for it to become healthy)..."
|
|
62
62
|
execute *app.deploy(target: endpoint)
|
|
63
63
|
run_hook "post-proxy-deploy", hosts: host.to_s, role: role.name
|
|
64
64
|
else
|
|
65
|
-
|
|
65
|
+
Dash::Cli::Healthcheck::Poller.wait_for_healthy(role: role) { health_status }
|
|
66
66
|
end
|
|
67
67
|
rescue => e
|
|
68
68
|
error "Failed to boot #{role} on #{host}"
|
|
@@ -104,48 +104,48 @@ class Kamal::Cli::App::Boot
|
|
|
104
104
|
run_stop_hook "post-app-stop", old_version
|
|
105
105
|
|
|
106
106
|
execute *app.clean_up_assets if assets?
|
|
107
|
-
execute *app.clean_up_error_pages if
|
|
107
|
+
execute *app.clean_up_error_pages if DASH.config.error_pages_path
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
# The new version is already live by the time the old one is stopped, so a failing
|
|
111
111
|
# drain hook must not fail the deploy — warn and stop the old container anyway.
|
|
112
112
|
def run_stop_hook(hook, old_version)
|
|
113
113
|
run_hook hook, hosts: host.to_s, role: role.name, version: old_version
|
|
114
|
-
rescue
|
|
114
|
+
rescue Dash::Cli::HookError => e
|
|
115
115
|
error "#{e.message}\nContinuing anyway: #{version} is already live for #{role} on #{host}."
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
def release_barrier
|
|
119
119
|
if barrier.open
|
|
120
|
-
info "First #{
|
|
120
|
+
info "First #{DASH.primary_role} container is healthy on #{host}, booting any other roles"
|
|
121
121
|
end
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
def wait_at_barrier
|
|
125
|
-
info "Waiting for the first healthy #{
|
|
125
|
+
info "Waiting for the first healthy #{DASH.primary_role} container before booting #{role} on #{host}..."
|
|
126
126
|
barrier.wait
|
|
127
|
-
info "First #{
|
|
128
|
-
rescue
|
|
129
|
-
info "First #{
|
|
127
|
+
info "First #{DASH.primary_role} container is healthy, booting #{role} on #{host}..."
|
|
128
|
+
rescue Dash::Cli::Healthcheck::Error
|
|
129
|
+
info "First #{DASH.primary_role} container is unhealthy, not booting #{role} on #{host}"
|
|
130
130
|
raise
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
def close_barrier
|
|
134
134
|
if barrier.close
|
|
135
|
-
info "First #{
|
|
135
|
+
info "First #{DASH.primary_role} container is unhealthy on #{host}, not booting any other roles"
|
|
136
136
|
end
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
def barrier_role?
|
|
140
|
-
role ==
|
|
140
|
+
role == DASH.primary_role
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
def app
|
|
144
|
-
@app ||=
|
|
144
|
+
@app ||= DASH.app(role: role, host: host)
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
def auditor
|
|
148
|
-
@auditor =
|
|
148
|
+
@auditor = DASH.auditor(role: role)
|
|
149
149
|
end
|
|
150
150
|
|
|
151
151
|
def audit(message)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Cli::App::ErrorPages
|
|
2
2
|
ERROR_PAGES_GLOB = "{4??.html,5??.html}"
|
|
3
3
|
|
|
4
4
|
attr_reader :host, :sshkit
|
|
@@ -10,10 +10,10 @@ class Kamal::Cli::App::ErrorPages
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def run
|
|
13
|
-
if
|
|
13
|
+
if DASH.config.error_pages_path
|
|
14
14
|
with_error_pages_tmpdir do |local_error_pages_dir|
|
|
15
|
-
execute *
|
|
16
|
-
upload! local_error_pages_dir,
|
|
15
|
+
execute *DASH.app.create_error_pages_directory
|
|
16
|
+
upload! local_error_pages_dir, DASH.config.proxy_boot.error_pages_directory, mode: "0700", recursive: true
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -21,10 +21,10 @@ class Kamal::Cli::App::ErrorPages
|
|
|
21
21
|
private
|
|
22
22
|
def with_error_pages_tmpdir
|
|
23
23
|
Dir.mktmpdir("kamal-error-pages") do |tmpdir|
|
|
24
|
-
error_pages_dir = File.join(tmpdir,
|
|
24
|
+
error_pages_dir = File.join(tmpdir, DASH.config.version)
|
|
25
25
|
FileUtils.mkdir(error_pages_dir)
|
|
26
26
|
|
|
27
|
-
if (files = Dir[File.join(
|
|
27
|
+
if (files = Dir[File.join(DASH.config.error_pages_path, ERROR_PAGES_GLOB)]).any?
|
|
28
28
|
FileUtils.cp(files, error_pages_dir)
|
|
29
29
|
yield error_pages_dir
|
|
30
30
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Cli::App::RolloutBoot
|
|
2
2
|
attr_reader :host, :role, :version, :sshkit
|
|
3
3
|
delegate :execute, :capture_with_info, :error, :upload!, to: :sshkit
|
|
4
4
|
|
|
@@ -18,7 +18,7 @@ class Kamal::Cli::App::RolloutBoot
|
|
|
18
18
|
stop_rollout_target
|
|
19
19
|
raise
|
|
20
20
|
end
|
|
21
|
-
rescue
|
|
21
|
+
rescue Dash::Cli::BootError => e
|
|
22
22
|
error e.message
|
|
23
23
|
raise
|
|
24
24
|
end
|
|
@@ -26,7 +26,7 @@ class Kamal::Cli::App::RolloutBoot
|
|
|
26
26
|
private
|
|
27
27
|
def ensure_not_already_deployed
|
|
28
28
|
if capture_with_info(*app.container_id_for_version(version), raise_on_non_zero_exit: false).present?
|
|
29
|
-
raise
|
|
29
|
+
raise Dash::Cli::BootError, "Version #{version} is already deployed for #{role} on #{host}, roll out a different version"
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -40,7 +40,7 @@ class Kamal::Cli::App::RolloutBoot
|
|
|
40
40
|
execute *app.run(hostname: hostname)
|
|
41
41
|
|
|
42
42
|
endpoint = capture_with_info(*app.container_id_for_version(version)).strip
|
|
43
|
-
raise
|
|
43
|
+
raise Dash::Cli::BootError, "Failed to get endpoint for #{role} on #{host}, did the container boot?" if endpoint.empty?
|
|
44
44
|
|
|
45
45
|
execute *app.rollout_deploy(target: endpoint)
|
|
46
46
|
end
|
|
@@ -50,10 +50,10 @@ class Kamal::Cli::App::RolloutBoot
|
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def app
|
|
53
|
-
@app ||=
|
|
53
|
+
@app ||= DASH.app(role: role, host: host)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def audit(message)
|
|
57
|
-
execute *
|
|
57
|
+
execute *DASH.auditor(role: role).record(message), verbosity: :debug
|
|
58
58
|
end
|
|
59
59
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Cli::App::SslCertificates
|
|
2
2
|
attr_reader :host, :role, :sshkit
|
|
3
3
|
delegate :execute, :info, :upload!, to: :sshkit
|
|
4
4
|
|
|
@@ -24,7 +24,7 @@ class Kamal::Cli::App::SslCertificates
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
# The client CA arrives the same way the server certificate does: as
|
|
27
|
-
# secret content named in .
|
|
27
|
+
# secret content named in .dash/secrets, resolved here at upload time.
|
|
28
28
|
if role.proxy.client_ca?
|
|
29
29
|
upload!(StringIO.new(role.proxy.client_ca_pem_content), role.proxy.host_client_ca, mode: "0644")
|
|
30
30
|
end
|
|
@@ -32,6 +32,6 @@ class Kamal::Cli::App::SslCertificates
|
|
|
32
32
|
|
|
33
33
|
private
|
|
34
34
|
def app
|
|
35
|
-
@app ||=
|
|
35
|
+
@app ||= DASH.app(role: role, host: host)
|
|
36
36
|
end
|
|
37
37
|
end
|