kamal 2.9.0 → 2.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd7c6e6e18ca7cc95712642dfdb5ec45c33e06b6a02750e5ee7a3f1ac3428ea2
4
- data.tar.gz: 1a8acfe5ec44636827ca70da1263289e6082359c58601acce9870d1d46ba750b
3
+ metadata.gz: 0a154bea7b15565394f37d8cbbfc8860e3d6ef337526779390ebd96d917d2d7e
4
+ data.tar.gz: a08c4cd341c5404cd9a5401b24918cdd32d498dbb778a655e1cb7f667030e519
5
5
  SHA512:
6
- metadata.gz: d1fb62392ddafc5b1fe6b54055121654bd73625eaf9808848ed60d7d40fdadf2938675b0bc881fca1297ee089f78b3768eefb96f5c10e9e8346265f20d9663e2
7
- data.tar.gz: 6fc4f87a3ea64ebdee5c3c666cdafa5b15a0f7b243f575b402d82a2c8eec5b3802a05c0b5a80f6856eb92c24647b65a7bbdb8a68fd208dc873f1cd55d725894e
6
+ metadata.gz: b09103e638d6d14d9605d3327928cf0343a80ff213e9e7f5f42d0c372c60ab78b13e30a983b1dc47e75cb17d7b705e94c98ea73077b8a2e1f87959f684e7a71d
7
+ data.tar.gz: db80e53f84048c1ee6a5f2d3a010469578cbeedb94826b2393dcd4552f9e063c70b42242b3ea705c659c02a9cc87b7311c8e372d106148bea5baaa261cf7811d
@@ -45,12 +45,14 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
45
45
  with_lock do
46
46
  with_accessory(name) do |accessory, hosts|
47
47
  on(hosts) do
48
- accessory.files.each do |(local, remote)|
48
+ accessory.files.each do |(local, config)|
49
+ remote = config[:host_path]
49
50
  accessory.ensure_local_file_present(local)
50
51
 
51
52
  execute *accessory.make_directory_for(remote)
52
53
  upload! local, remote
53
- execute :chmod, "755", remote
54
+ execute :chmod, config[:mode], remote
55
+ execute :chown, config[:owner], remote if config[:owner]
54
56
  end
55
57
  end
56
58
  end
@@ -62,8 +64,10 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
62
64
  with_lock do
63
65
  with_accessory(name) do |accessory, hosts|
64
66
  on(hosts) do
65
- accessory.directories.keys.each do |host_path|
66
- execute *accessory.make_directory(host_path)
67
+ accessory.directories.each do |(local, config)|
68
+ execute *accessory.make_directory(local)
69
+ execute :chmod, config[:mode], local if config[:mode]
70
+ execute :chown, config[:owner], local if config[:owner]
67
71
  end
68
72
  end
69
73
  end
@@ -56,7 +56,7 @@ class Kamal::Cli::App::Boot
56
56
  raise Kamal::Cli::BootError, "Failed to get endpoint for #{role} on #{host}, did the container boot?" if endpoint.empty?
57
57
  execute *app.deploy(target: endpoint)
58
58
  else
59
- Kamal::Cli::Healthcheck::Poller.wait_for_healthy(pause_after_ready: true) { capture_with_info(*app.status(version: version)) }
59
+ Kamal::Cli::Healthcheck::Poller.wait_for_healthy { capture_with_info(*app.status(version: version)) }
60
60
  end
61
61
  rescue => e
62
62
  error "Failed to boot #{role} on #{host}"
data/lib/kamal/cli/app.rb CHANGED
@@ -23,10 +23,8 @@ class Kamal::Cli::App < Kamal::Cli::Base
23
23
  host_list = Array(hosts).join(",")
24
24
  run_hook "pre-app-boot", hosts: host_list
25
25
 
26
- on(hosts) do |host|
27
- KAMAL.roles_on(host).each do |role|
28
- Kamal::Cli::App::Boot.new(host, role, self, version, barrier).run
29
- end
26
+ on_roles(KAMAL.roles, hosts: hosts, parallel: KAMAL.config.boot.parallel_roles) do |host, role|
27
+ Kamal::Cli::App::Boot.new(host, role, self, version, barrier).run
30
28
  end
31
29
 
32
30
  run_hook "post-app-boot", hosts: host_list
@@ -45,21 +43,17 @@ class Kamal::Cli::App < Kamal::Cli::Base
45
43
  desc "start", "Start existing app container on servers"
46
44
  def start
47
45
  with_lock do
48
- on(KAMAL.app_hosts) do |host|
49
- roles = KAMAL.roles_on(host)
50
-
51
- roles.each do |role|
52
- app = KAMAL.app(role: role, host: host)
53
- execute *KAMAL.auditor.record("Started app version #{KAMAL.config.version}"), verbosity: :debug
54
- execute *app.start, raise_on_non_zero_exit: false
46
+ on_roles(KAMAL.roles, hosts: KAMAL.app_hosts, parallel: KAMAL.config.boot.parallel_roles) do |host, role|
47
+ app = KAMAL.app(role: role, host: host)
48
+ execute *KAMAL.auditor.record("Started app version #{KAMAL.config.version}"), verbosity: :debug
49
+ execute *app.start, raise_on_non_zero_exit: false
55
50
 
56
- if role.running_proxy?
57
- version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip
58
- endpoint = capture_with_info(*app.container_id_for_version(version)).strip
59
- raise Kamal::Cli::BootError, "Failed to get endpoint for #{role} on #{host}, did the container boot?" if endpoint.empty?
51
+ if role.running_proxy?
52
+ version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip
53
+ endpoint = capture_with_info(*app.container_id_for_version(version)).strip
54
+ raise Kamal::Cli::BootError, "Failed to get endpoint for #{role} on #{host}, did the container boot?" if endpoint.empty?
60
55
 
61
- execute *app.deploy(target: endpoint)
62
- end
56
+ execute *app.deploy(target: endpoint)
63
57
  end
64
58
  end
65
59
  end
@@ -68,23 +62,19 @@ class Kamal::Cli::App < Kamal::Cli::Base
68
62
  desc "stop", "Stop app container on servers"
69
63
  def stop
70
64
  with_lock do
71
- on(KAMAL.app_hosts) do |host|
72
- roles = KAMAL.roles_on(host)
73
-
74
- roles.each do |role|
75
- app = KAMAL.app(role: role, host: host)
76
- execute *KAMAL.auditor.record("Stopped app", role: role), verbosity: :debug
77
-
78
- if role.running_proxy?
79
- version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip
80
- endpoint = capture_with_info(*app.container_id_for_version(version)).strip
81
- if endpoint.present?
82
- execute *app.remove, raise_on_non_zero_exit: false
83
- end
84
- end
65
+ on_roles(KAMAL.roles, hosts: KAMAL.app_hosts, parallel: KAMAL.config.boot.parallel_roles) do |host, role|
66
+ app = KAMAL.app(role: role, host: host)
67
+ execute *KAMAL.auditor.record("Stopped app", role: role), verbosity: :debug
85
68
 
86
- execute *app.stop, raise_on_non_zero_exit: false
69
+ if role.running_proxy?
70
+ version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip
71
+ endpoint = capture_with_info(*app.container_id_for_version(version)).strip
72
+ if endpoint.present?
73
+ execute *app.remove, raise_on_non_zero_exit: false
74
+ end
87
75
  end
76
+
77
+ execute *app.stop, raise_on_non_zero_exit: false
88
78
  end
89
79
  end
90
80
  end
@@ -93,12 +83,8 @@ class Kamal::Cli::App < Kamal::Cli::Base
93
83
  desc "details", "Show details about app containers"
94
84
  def details
95
85
  quiet = options[:quiet]
96
- on(KAMAL.app_hosts) do |host|
97
- roles = KAMAL.roles_on(host)
98
-
99
- roles.each do |role|
100
- puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).info), quiet: quiet
101
- end
86
+ on_roles(KAMAL.roles, hosts: KAMAL.app_hosts) do |host, role|
87
+ puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).info), quiet: quiet
102
88
  end
103
89
  end
104
90
 
@@ -145,13 +131,9 @@ class Kamal::Cli::App < Kamal::Cli::Base
145
131
  using_version(options[:version] || current_running_version) do |version|
146
132
  say "Launching command with version #{version} from existing container...", :magenta
147
133
 
148
- on(KAMAL.app_hosts) do |host|
149
- roles = KAMAL.roles_on(host)
150
-
151
- roles.each do |role|
152
- execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on app version #{version}", role: role), verbosity: :debug
153
- puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).execute_in_existing_container(cmd, env: env)), quiet: quiet
154
- end
134
+ on_roles(KAMAL.roles, hosts: KAMAL.app_hosts) do |host, role|
135
+ execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on app version #{version}", role: role), verbosity: :debug
136
+ puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).execute_in_existing_container(cmd, env: env)), quiet: quiet
155
137
  end
156
138
  end
157
139
 
@@ -159,15 +141,11 @@ class Kamal::Cli::App < Kamal::Cli::Base
159
141
  say "Get most recent version available as an image...", :magenta unless options[:version]
160
142
  using_version(version_or_latest) do |version|
161
143
  say "Launching command with version #{version} from new container...", :magenta
162
- on(KAMAL.app_hosts) do |host|
163
- execute *KAMAL.registry.login
164
-
165
- roles = KAMAL.roles_on(host)
144
+ on(KAMAL.app_hosts) { execute *KAMAL.registry.login }
166
145
 
167
- roles.each do |role|
168
- execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on app version #{version}"), verbosity: :debug
169
- puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).execute_in_new_container(cmd, env: env, detach: detach)), quiet: quiet
170
- end
146
+ on_roles(KAMAL.roles, hosts: KAMAL.app_hosts) do |host, role|
147
+ execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on app version #{version}"), verbosity: :debug
148
+ puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).execute_in_new_container(cmd, env: env, detach: detach)), quiet: quiet
171
149
  end
172
150
  end
173
151
  end
@@ -186,21 +164,17 @@ class Kamal::Cli::App < Kamal::Cli::Base
186
164
  stop = options[:stop]
187
165
 
188
166
  with_lock_if_stopping do
189
- on(KAMAL.app_hosts) do |host|
190
- roles = KAMAL.roles_on(host)
191
-
192
- roles.each do |role|
193
- app = KAMAL.app(role: role, host: host)
194
- versions = capture_with_info(*app.list_versions, raise_on_non_zero_exit: false).split("\n")
195
- versions -= [ capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip ]
196
-
197
- versions.each do |version|
198
- if stop
199
- puts_by_host host, "Stopping stale container for role #{role} with version #{version}", quiet: quiet
200
- execute *app.stop(version: version), raise_on_non_zero_exit: false
201
- else
202
- puts_by_host host, "Detected stale container for role #{role} with version #{version} (use `kamal app stale_containers --stop` to stop)", quiet: quiet
203
- end
167
+ on_roles(KAMAL.roles, hosts: KAMAL.app_hosts) do |host, role|
168
+ app = KAMAL.app(role: role, host: host)
169
+ versions = capture_with_info(*app.list_versions, raise_on_non_zero_exit: false).split("\n")
170
+ versions -= [ capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip ]
171
+
172
+ versions.each do |version|
173
+ if stop
174
+ puts_by_host host, "Stopping stale container for role #{role} with version #{version}", quiet: quiet
175
+ execute *app.stop(version: version), raise_on_non_zero_exit: false
176
+ else
177
+ puts_by_host host, "Detected stale container for role #{role} with version #{version} (use `kamal app stale_containers --stop` to stop)", quiet: quiet
204
178
  end
205
179
  end
206
180
  end
@@ -247,15 +221,11 @@ class Kamal::Cli::App < Kamal::Cli::Base
247
221
  else
248
222
  lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set
249
223
 
250
- on(KAMAL.app_hosts) do |host|
251
- roles = KAMAL.roles_on(host)
252
-
253
- roles.each do |role|
254
- begin
255
- puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).logs(container_id: container_id, timestamps: timestamps, since: since, lines: lines, grep: grep, grep_options: grep_options)), quiet: quiet
256
- rescue SSHKit::Command::Failed
257
- puts_by_host host, "Nothing found", quiet: quiet
258
- end
224
+ on_roles(KAMAL.roles, hosts: KAMAL.app_hosts) do |host, role|
225
+ begin
226
+ puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).logs(container_id: container_id, timestamps: timestamps, since: since, lines: lines, grep: grep, grep_options: grep_options)), quiet: quiet
227
+ rescue SSHKit::Command::Failed
228
+ puts_by_host host, "Nothing found", quiet: quiet
259
229
  end
260
230
  end
261
231
  end
@@ -274,12 +244,8 @@ class Kamal::Cli::App < Kamal::Cli::Base
274
244
  desc "live", "Set the app to live mode"
275
245
  def live
276
246
  with_lock do
277
- on(KAMAL.proxy_hosts) do |host|
278
- roles = KAMAL.roles_on(host)
279
-
280
- roles.each do |role|
281
- execute *KAMAL.app(role: role, host: host).live if role.running_proxy?
282
- end
247
+ on_roles(KAMAL.roles, hosts: KAMAL.proxy_hosts) do |host, role|
248
+ execute *KAMAL.app(role: role, host: host).live if role.running_proxy?
283
249
  end
284
250
  end
285
251
  end
@@ -291,12 +257,8 @@ class Kamal::Cli::App < Kamal::Cli::Base
291
257
  maintenance_options = { drain_timeout: options[:drain_timeout] || KAMAL.config.drain_timeout, message: options[:message] }
292
258
 
293
259
  with_lock do
294
- on(KAMAL.proxy_hosts) do |host|
295
- roles = KAMAL.roles_on(host)
296
-
297
- roles.each do |role|
298
- execute *KAMAL.app(role: role, host: host).maintenance(**maintenance_options) if role.running_proxy?
299
- end
260
+ on_roles(KAMAL.roles, hosts: KAMAL.proxy_hosts) do |host, role|
261
+ execute *KAMAL.app(role: role, host: host).maintenance(**maintenance_options) if role.running_proxy?
300
262
  end
301
263
  end
302
264
  end
@@ -304,13 +266,9 @@ class Kamal::Cli::App < Kamal::Cli::Base
304
266
  desc "remove_container [VERSION]", "Remove app container with given version from servers", hide: true
305
267
  def remove_container(version)
306
268
  with_lock do
307
- on(KAMAL.app_hosts) do |host|
308
- roles = KAMAL.roles_on(host)
309
-
310
- roles.each do |role|
311
- execute *KAMAL.auditor.record("Removed app container with version #{version}", role: role), verbosity: :debug
312
- execute *KAMAL.app(role: role, host: host).remove_container(version: version)
313
- end
269
+ on_roles(KAMAL.roles, hosts: KAMAL.app_hosts) do |host, role|
270
+ execute *KAMAL.auditor.record("Removed app container with version #{version}", role: role), verbosity: :debug
271
+ execute *KAMAL.app(role: role, host: host).remove_container(version: version)
314
272
  end
315
273
  end
316
274
  end
@@ -318,13 +276,9 @@ class Kamal::Cli::App < Kamal::Cli::Base
318
276
  desc "remove_containers", "Remove all app containers from servers", hide: true
319
277
  def remove_containers
320
278
  with_lock do
321
- on(KAMAL.app_hosts) do |host|
322
- roles = KAMAL.roles_on(host)
323
-
324
- roles.each do |role|
325
- execute *KAMAL.auditor.record("Removed all app containers", role: role), verbosity: :debug
326
- execute *KAMAL.app(role: role, host: host).remove_containers
327
- end
279
+ on_roles(KAMAL.roles, hosts: KAMAL.app_hosts) do |host, role|
280
+ execute *KAMAL.auditor.record("Removed all app containers", role: role), verbosity: :debug
281
+ execute *KAMAL.app(role: role, host: host).remove_containers
328
282
  end
329
283
  end
330
284
  end
@@ -332,7 +286,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
332
286
  desc "remove_images", "Remove all app images from servers", hide: true
333
287
  def remove_images
334
288
  with_lock do
335
- on(KAMAL.app_hosts) do
289
+ on(hosts_removing_all_roles) do
336
290
  execute *KAMAL.auditor.record("Removed all app images"), verbosity: :debug
337
291
  execute *KAMAL.app.remove_images
338
292
  end
@@ -342,14 +296,8 @@ class Kamal::Cli::App < Kamal::Cli::Base
342
296
  desc "remove_app_directories", "Remove the app directories from servers", hide: true
343
297
  def remove_app_directories
344
298
  with_lock do
345
- on(KAMAL.app_hosts) do |host|
346
- roles = KAMAL.roles_on(host)
347
-
348
- roles.each do |role|
349
- execute *KAMAL.auditor.record("Removed #{KAMAL.config.app_directory}", role: role), verbosity: :debug
350
- execute *KAMAL.server.remove_app_directory, raise_on_non_zero_exit: false
351
- end
352
-
299
+ on(hosts_removing_all_roles) do |host|
300
+ execute *KAMAL.server.remove_app_directory, raise_on_non_zero_exit: false
353
301
  execute *KAMAL.auditor.record("Removed #{KAMAL.config.app_directory}"), verbosity: :debug
354
302
  execute *KAMAL.app.remove_proxy_app_directory, raise_on_non_zero_exit: false
355
303
  end
@@ -366,6 +314,10 @@ class Kamal::Cli::App < Kamal::Cli::Base
366
314
  end
367
315
 
368
316
  private
317
+ def hosts_removing_all_roles
318
+ KAMAL.app_hosts.select { |host| KAMAL.roles_on(host).map(&:name).sort == KAMAL.config.host_roles(host.to_s).map(&:name).sort }
319
+ end
320
+
369
321
  def using_version(new_version)
370
322
  if new_version
371
323
  begin
@@ -1,7 +1,7 @@
1
1
  module Kamal::Cli::Healthcheck::Poller
2
2
  extend self
3
3
 
4
- def wait_for_healthy(role, &block)
4
+ def wait_for_healthy(&block)
5
5
  attempt = 1
6
6
  timeout_at = Time.now + KAMAL.config.deploy_timeout
7
7
  readiness_delay = KAMAL.config.readiness_delay
@@ -11,13 +11,13 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
11
11
  on(KAMAL.proxy_hosts) do |host|
12
12
  execute *KAMAL.registry.login
13
13
 
14
- version = capture_with_info(*KAMAL.proxy.version).strip.presence
14
+ version = capture_with_info(*KAMAL.proxy(host).version).strip.presence
15
15
 
16
- if version && Kamal::Utils.older_version?(version, Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION)
17
- raise "kamal-proxy version #{version} is too old, run `kamal proxy reboot` in order to update to at least #{Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION}"
16
+ if version && Kamal::Utils.older_version?(version, Kamal::Configuration::Proxy::Run::MINIMUM_VERSION)
17
+ raise "kamal-proxy version #{version} is too old, run `kamal proxy reboot` in order to update to at least #{Kamal::Configuration::Proxy::Run::MINIMUM_VERSION}"
18
18
  end
19
- execute *KAMAL.proxy.ensure_apps_config_directory
20
- execute *KAMAL.proxy.start_or_run
19
+ execute *KAMAL.proxy(host).ensure_apps_config_directory
20
+ execute *KAMAL.proxy(host).start_or_run
21
21
  end
22
22
  end
23
23
  end
@@ -25,9 +25,9 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
25
25
  desc "boot_config <set|get|reset>", "Manage kamal-proxy boot configuration"
26
26
  option :publish, type: :boolean, default: true, desc: "Publish the proxy ports on the host"
27
27
  option :publish_host_ip, type: :string, repeatable: true, default: nil, desc: "Host IP address to bind HTTP/HTTPS traffic to. Defaults to all interfaces"
28
- option :http_port, type: :numeric, default: Kamal::Configuration::Proxy::Boot::DEFAULT_HTTP_PORT, desc: "HTTP port to publish on the host"
29
- option :https_port, type: :numeric, default: Kamal::Configuration::Proxy::Boot::DEFAULT_HTTPS_PORT, desc: "HTTPS port to publish on the host"
30
- option :log_max_size, type: :string, default: Kamal::Configuration::Proxy::Boot::DEFAULT_LOG_MAX_SIZE, desc: "Max size of proxy logs"
28
+ option :http_port, type: :numeric, default: Kamal::Configuration::Proxy::Run::DEFAULT_HTTP_PORT, desc: "HTTP port to publish on the host"
29
+ option :https_port, type: :numeric, default: Kamal::Configuration::Proxy::Run::DEFAULT_HTTPS_PORT, desc: "HTTPS port to publish on the host"
30
+ option :log_max_size, type: :string, default: Kamal::Configuration::Proxy::Run::DEFAULT_LOG_MAX_SIZE, desc: "Max size of proxy logs"
31
31
  option :registry, type: :string, default: nil, desc: "Registry to use for the proxy image"
32
32
  option :repository, type: :string, default: nil, desc: "Repository for the proxy image"
33
33
  option :image_version, type: :string, default: nil, desc: "Version of the proxy to run"
@@ -35,6 +35,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
35
35
  option :debug, type: :boolean, default: false, desc: "Whether to run the proxy in debug mode"
36
36
  option :docker_options, type: :array, default: [], desc: "Docker options to pass to the proxy container", banner: "option=value option2=value2"
37
37
  def boot_config(subcommand)
38
+ say "The proxy boot_config command is deprecated - set the config in the deploy YAML at proxy/run instead", :yellow
38
39
  proxy_boot_config = KAMAL.config.proxy_boot
39
40
 
40
41
  case subcommand
@@ -58,42 +59,44 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
58
59
  run_command = "kamal-proxy run #{Kamal::Utils.optionize(run_command_options).join(" ")}" if run_command_options.any?
59
60
 
60
61
  on(KAMAL.proxy_hosts) do |host|
61
- execute(*KAMAL.proxy.ensure_proxy_directory)
62
+ proxy = KAMAL.proxy(host)
63
+ execute(*proxy.ensure_proxy_directory)
62
64
  if boot_options != proxy_boot_config.default_boot_options
63
65
  upload! StringIO.new(boot_options.join(" ")), proxy_boot_config.options_file
64
66
  else
65
- execute *KAMAL.proxy.reset_boot_options, raise_on_non_zero_exit: false
67
+ execute *proxy.reset_boot_options, raise_on_non_zero_exit: false
66
68
  end
67
69
 
68
70
  if image != proxy_boot_config.image_default
69
71
  upload! StringIO.new(image), proxy_boot_config.image_file
70
72
  else
71
- execute *KAMAL.proxy.reset_image, raise_on_non_zero_exit: false
73
+ execute *proxy.reset_image, raise_on_non_zero_exit: false
72
74
  end
73
75
 
74
76
  if image_version
75
77
  upload! StringIO.new(image_version), proxy_boot_config.image_version_file
76
78
  else
77
- execute *KAMAL.proxy.reset_image_version, raise_on_non_zero_exit: false
79
+ execute *proxy.reset_image_version, raise_on_non_zero_exit: false
78
80
  end
79
81
 
80
82
  if run_command
81
83
  upload! StringIO.new(run_command), proxy_boot_config.run_command_file
82
84
  else
83
- execute *KAMAL.proxy.reset_run_command, raise_on_non_zero_exit: false
85
+ execute *proxy.reset_run_command, raise_on_non_zero_exit: false
84
86
  end
85
87
  end
86
88
  when "get"
87
89
 
88
90
  on(KAMAL.proxy_hosts) do |host|
89
- puts "Host #{host}: #{capture_with_info(*KAMAL.proxy.boot_config)}"
91
+ puts "Host #{host}: #{capture_with_info(*KAMAL.proxy(host).boot_config)}"
90
92
  end
91
93
  when "reset"
92
94
  on(KAMAL.proxy_hosts) do |host|
93
- execute *KAMAL.proxy.reset_boot_options, raise_on_non_zero_exit: false
94
- execute *KAMAL.proxy.reset_image, raise_on_non_zero_exit: false
95
- execute *KAMAL.proxy.reset_image_version, raise_on_non_zero_exit: false
96
- execute *KAMAL.proxy.reset_run_command, raise_on_non_zero_exit: false
95
+ proxy = KAMAL.proxy(host)
96
+ execute *proxy.reset_boot_options, raise_on_non_zero_exit: false
97
+ execute *proxy.reset_image, raise_on_non_zero_exit: false
98
+ execute *proxy.reset_image_version, raise_on_non_zero_exit: false
99
+ execute *proxy.reset_run_command, raise_on_non_zero_exit: false
97
100
  end
98
101
  else
99
102
  raise ArgumentError, "Unknown boot_config subcommand #{subcommand}"
@@ -111,15 +114,16 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
111
114
  host_list = Array(hosts).join(",")
112
115
  run_hook "pre-proxy-reboot", hosts: host_list
113
116
  on(hosts) do |host|
117
+ proxy = KAMAL.proxy(host)
114
118
  execute *KAMAL.auditor.record("Rebooted proxy"), verbosity: :debug
115
119
  execute *KAMAL.registry.login
116
120
 
117
121
  "Stopping and removing kamal-proxy on #{host}, if running..."
118
- execute *KAMAL.proxy.stop, raise_on_non_zero_exit: false
119
- execute *KAMAL.proxy.remove_container
120
- execute *KAMAL.proxy.ensure_apps_config_directory
122
+ execute *proxy.stop, raise_on_non_zero_exit: false
123
+ execute *proxy.remove_container
124
+ execute *proxy.ensure_apps_config_directory
121
125
 
122
- execute *KAMAL.proxy.run
126
+ execute *proxy.run
123
127
  end
124
128
  run_hook "post-proxy-reboot", hosts: host_list
125
129
  end
@@ -140,16 +144,17 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
140
144
  say "Upgrading proxy on #{host_list}...", :magenta
141
145
  run_hook "pre-proxy-reboot", hosts: host_list
142
146
  on(hosts) do |host|
147
+ proxy = KAMAL.proxy(host)
143
148
  execute *KAMAL.auditor.record("Rebooted proxy"), verbosity: :debug
144
149
  execute *KAMAL.registry.login
145
150
 
146
151
  "Stopping and removing Traefik on #{host}, if running..."
147
- execute *KAMAL.proxy.cleanup_traefik
152
+ execute *proxy.cleanup_traefik
148
153
 
149
154
  "Stopping and removing kamal-proxy on #{host}, if running..."
150
- execute *KAMAL.proxy.stop, raise_on_non_zero_exit: false
151
- execute *KAMAL.proxy.remove_container
152
- execute *KAMAL.proxy.remove_image
155
+ execute *proxy.stop, raise_on_non_zero_exit: false
156
+ execute *proxy.remove_container
157
+ execute *proxy.remove_image
153
158
  end
154
159
 
155
160
  KAMAL.with_specific_hosts(hosts) do
@@ -172,7 +177,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
172
177
  with_lock do
173
178
  on(KAMAL.proxy_hosts) do |host|
174
179
  execute *KAMAL.auditor.record("Started proxy"), verbosity: :debug
175
- execute *KAMAL.proxy.start
180
+ execute *KAMAL.proxy(host).start
176
181
  end
177
182
  end
178
183
  end
@@ -182,7 +187,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
182
187
  with_lock do
183
188
  on(KAMAL.proxy_hosts) do |host|
184
189
  execute *KAMAL.auditor.record("Stopped proxy"), verbosity: :debug
185
- execute *KAMAL.proxy.stop, raise_on_non_zero_exit: false
190
+ execute *KAMAL.proxy(host).stop, raise_on_non_zero_exit: false
186
191
  end
187
192
  end
188
193
  end
@@ -198,7 +203,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
198
203
  desc "details", "Show details about proxy container from servers"
199
204
  def details
200
205
  quiet = options[:quiet]
201
- on(KAMAL.proxy_hosts) { |host| puts_by_host host, capture_with_info(*KAMAL.proxy.info), type: "Proxy", quiet: quiet }
206
+ on(KAMAL.proxy_hosts) { |host| puts_by_host host, capture_with_info(*KAMAL.proxy(host).info), type: "Proxy", quiet: quiet }
202
207
  end
203
208
 
204
209
  desc "logs", "Show log lines from proxy on servers"
@@ -213,16 +218,17 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
213
218
 
214
219
  if options[:follow]
215
220
  run_locally do
221
+ proxy = KAMAL.proxy(KAMAL.primary_host)
216
222
  info "Following logs on #{KAMAL.primary_host}..."
217
- info KAMAL.proxy.follow_logs(host: KAMAL.primary_host, timestamps: timestamps, grep: grep)
218
- exec KAMAL.proxy.follow_logs(host: KAMAL.primary_host, timestamps: timestamps, grep: grep)
223
+ info proxy.follow_logs(host: KAMAL.primary_host, timestamps: timestamps, grep: grep)
224
+ exec proxy.follow_logs(host: KAMAL.primary_host, timestamps: timestamps, grep: grep)
219
225
  end
220
226
  else
221
227
  since = options[:since]
222
228
  lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set
223
229
 
224
230
  on(KAMAL.proxy_hosts) do |host|
225
- puts_by_host host, capture(*KAMAL.proxy.logs(timestamps: timestamps, since: since, lines: lines, grep: grep)), type: "Proxy"
231
+ puts_by_host host, capture(*KAMAL.proxy(host).logs(timestamps: timestamps, since: since, lines: lines, grep: grep)), type: "Proxy"
226
232
  end
227
233
  end
228
234
  end
@@ -245,7 +251,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
245
251
  with_lock do
246
252
  on(KAMAL.proxy_hosts) do
247
253
  execute *KAMAL.auditor.record("Removed proxy container"), verbosity: :debug
248
- execute *KAMAL.proxy.remove_container
254
+ execute *KAMAL.proxy(host).remove_container
249
255
  end
250
256
  end
251
257
  end
@@ -255,7 +261,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
255
261
  with_lock do
256
262
  on(KAMAL.proxy_hosts) do
257
263
  execute *KAMAL.auditor.record("Removed proxy image"), verbosity: :debug
258
- execute *KAMAL.proxy.remove_image
264
+ execute *KAMAL.proxy(host).remove_image
259
265
  end
260
266
  end
261
267
  end
@@ -264,7 +270,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
264
270
  def remove_proxy_directory
265
271
  with_lock do
266
272
  on(KAMAL.proxy_hosts) do
267
- execute *KAMAL.proxy.remove_proxy_directory, raise_on_non_zero_exit: false
273
+ execute *KAMAL.proxy(host).remove_proxy_directory, raise_on_non_zero_exit: false
268
274
  end
269
275
  end
270
276
  end
@@ -12,8 +12,9 @@ class Kamal::Cli::Secrets < Kamal::Cli::Base
12
12
  end
13
13
 
14
14
  results = adapter.fetch(secrets, **options.slice(:account, :from).symbolize_keys)
15
+ json = JSON.dump(results)
15
16
 
16
- return_or_puts JSON.dump(results).shellescape, inline: options[:inline]
17
+ return_or_puts options[:inline] ? json.shellescape : json, inline: options[:inline]
17
18
  end
18
19
 
19
20
  desc "extract", "Extract a single secret from the results of a fetch call"
@@ -109,8 +109,8 @@ class Kamal::Commander
109
109
  @commands[:lock] ||= Kamal::Commands::Lock.new(config)
110
110
  end
111
111
 
112
- def proxy
113
- @commands[:proxy] ||= Kamal::Commands::Proxy.new(config)
112
+ def proxy(host)
113
+ Kamal::Commands::Proxy.new(config, host: host)
114
114
  end
115
115
 
116
116
  def prune
@@ -23,7 +23,7 @@ class Kamal::Commands::App < Kamal::Commands::Base
23
23
  "--env", "KAMAL_CONTAINER_NAME=\"#{container_name}\"",
24
24
  "--env", "KAMAL_VERSION=\"#{config.version}\"",
25
25
  "--env", "KAMAL_HOST=\"#{host}\"",
26
- "--env", "KAMAL_DESTINATION=\"#{config.destination}\"",
26
+ *([ "--env", "KAMAL_DESTINATION=\"#{config.destination}\"" ] if config.destination),
27
27
  *role.env_args(host),
28
28
  *role.logging_args,
29
29
  *config.volume_args,
@@ -1,8 +1,27 @@
1
1
  class Kamal::Commands::Proxy < Kamal::Commands::Base
2
2
  delegate :argumentize, :optionize, to: Kamal::Utils
3
+ attr_reader :proxy_run_config
4
+
5
+ def initialize(config, host:)
6
+ super(config)
7
+ @proxy_run_config = config.proxy_run(host)
8
+ end
3
9
 
4
10
  def run
5
- pipe boot_config, xargs(docker_run)
11
+ if proxy_run_config
12
+ docker \
13
+ :run,
14
+ "--name", container_name,
15
+ "--network", "kamal",
16
+ "--detach",
17
+ "--restart", "unless-stopped",
18
+ "--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy",
19
+ *proxy_run_config.docker_options_args,
20
+ *proxy_run_config.image,
21
+ *proxy_run_config.run_command
22
+ else
23
+ pipe boot_config, xargs(docker_run)
24
+ end
6
25
  end
7
26
 
8
27
  def start
@@ -82,7 +101,7 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base
82
101
  end
83
102
 
84
103
  def read_image_version
85
- read_file(config.proxy_boot.image_version_file, default: Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION)
104
+ read_file(config.proxy_boot.image_version_file, default: Kamal::Configuration::Proxy::Run::MINIMUM_VERSION)
86
105
  end
87
106
 
88
107
  def read_run_command