kamal 1.6.0 → 1.7.0

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kamal/cli/accessory.rb +5 -3
  3. data/lib/kamal/cli/app.rb +6 -3
  4. data/lib/kamal/cli/build.rb +13 -10
  5. data/lib/kamal/cli/healthcheck/poller.rb +2 -2
  6. data/lib/kamal/cli/main.rb +14 -2
  7. data/lib/kamal/cli/registry.rb +9 -10
  8. data/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +1 -1
  9. data/lib/kamal/cli/traefik.rb +5 -3
  10. data/lib/kamal/cli.rb +1 -1
  11. data/lib/kamal/commands/accessory.rb +4 -4
  12. data/lib/kamal/commands/app/logging.rb +4 -4
  13. data/lib/kamal/commands/builder/base.rb +13 -0
  14. data/lib/kamal/commands/builder/multiarch/remote.rb +10 -0
  15. data/lib/kamal/commands/builder/multiarch.rb +4 -0
  16. data/lib/kamal/commands/builder/native/cached.rb +10 -1
  17. data/lib/kamal/commands/builder/native/remote.rb +8 -0
  18. data/lib/kamal/commands/builder.rb +17 -11
  19. data/lib/kamal/commands/registry.rb +4 -13
  20. data/lib/kamal/commands/traefik.rb +8 -47
  21. data/lib/kamal/configuration/accessory.rb +30 -41
  22. data/lib/kamal/configuration/boot.rb +9 -4
  23. data/lib/kamal/configuration/builder.rb +33 -33
  24. data/lib/kamal/configuration/docs/accessory.yml +90 -0
  25. data/lib/kamal/configuration/docs/boot.yml +19 -0
  26. data/lib/kamal/configuration/docs/builder.yml +107 -0
  27. data/lib/kamal/configuration/docs/configuration.yml +157 -0
  28. data/lib/kamal/configuration/docs/env.yml +72 -0
  29. data/lib/kamal/configuration/docs/healthcheck.yml +59 -0
  30. data/lib/kamal/configuration/docs/logging.yml +21 -0
  31. data/lib/kamal/configuration/docs/registry.yml +49 -0
  32. data/lib/kamal/configuration/docs/role.yml +52 -0
  33. data/lib/kamal/configuration/docs/servers.yml +27 -0
  34. data/lib/kamal/configuration/docs/ssh.yml +46 -0
  35. data/lib/kamal/configuration/docs/sshkit.yml +23 -0
  36. data/lib/kamal/configuration/docs/traefik.yml +62 -0
  37. data/lib/kamal/configuration/env/tag.rb +1 -1
  38. data/lib/kamal/configuration/env.rb +10 -14
  39. data/lib/kamal/configuration/healthcheck.rb +63 -0
  40. data/lib/kamal/configuration/logging.rb +33 -0
  41. data/lib/kamal/configuration/registry.rb +31 -0
  42. data/lib/kamal/configuration/role.rb +53 -65
  43. data/lib/kamal/configuration/servers.rb +18 -0
  44. data/lib/kamal/configuration/ssh.rb +11 -8
  45. data/lib/kamal/configuration/sshkit.rb +9 -7
  46. data/lib/kamal/configuration/traefik.rb +60 -0
  47. data/lib/kamal/configuration/validation.rb +27 -0
  48. data/lib/kamal/configuration/validator/accessory.rb +9 -0
  49. data/lib/kamal/configuration/validator/builder.rb +9 -0
  50. data/lib/kamal/configuration/validator/env.rb +54 -0
  51. data/lib/kamal/configuration/validator/registry.rb +25 -0
  52. data/lib/kamal/configuration/validator/role.rb +11 -0
  53. data/lib/kamal/configuration/validator/servers.rb +7 -0
  54. data/lib/kamal/configuration/validator.rb +140 -0
  55. data/lib/kamal/configuration.rb +41 -66
  56. data/lib/kamal/version.rb +1 -1
  57. data/lib/kamal.rb +2 -0
  58. metadata +49 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1386c468f912402e6ed544a4e65bd3c0bdca8840cc3c519c5251b7ec5e89931b
4
- data.tar.gz: 025ffc718735a857a03bfb06ee2498e33caf3d04e1e88cfd43baa753413b2fea
3
+ metadata.gz: 30a8c6964442e363d08edf8ad8c8b5ae835308392b330ec9e1ba8c659916bb04
4
+ data.tar.gz: fce971fac71c529d90bebf6ae1b28fb617d8c34a18cc7d244e0a845238891f22
5
5
  SHA512:
6
- metadata.gz: 051e11bfe7e3d23bdac103fa39a750b5ce10bfe29b9ce642239bc2a1752080bbef995b5075a2143cd0863cbe57dffb96ce97f75630863ba25f50d03a5e27cf5e
7
- data.tar.gz: b0d979ab7b2dc0e1fd8592d39cb5856eae5b8f9aca8e49fe726785132fae5455ee39c7c607b256d8d18ba1546af576e28c4a447c334f59ce8aba8e0e1af56c5e
6
+ metadata.gz: '097ba4ef7a4956a22b89354a648319152224b48e77a8c32e0757462402508773b61d1b238b34d9b8f16f9d24c8dad12e118ba23e669b6a1388d5a09f73296925'
7
+ data.tar.gz: f13f8f4dd704a559940313c245e5bde92915c77a716d01e3f69b5f825ef2c122bd840b9a9f47a4eb54f5555a87bced74dcf8c46394f53941211fdc0d66d5567b
@@ -149,23 +149,25 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
149
149
  option :since, aliases: "-s", desc: "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)"
150
150
  option :lines, type: :numeric, aliases: "-n", desc: "Number of log lines to pull from each server"
151
151
  option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)"
152
+ option :grep_options, aliases: "-o", desc: "Additional options supplied to grep"
152
153
  option :follow, aliases: "-f", desc: "Follow logs on primary server (or specific host set by --hosts)"
153
154
  def logs(name)
154
155
  with_accessory(name) do |accessory, hosts|
155
156
  grep = options[:grep]
157
+ grep_options = options[:grep_options]
156
158
 
157
159
  if options[:follow]
158
160
  run_locally do
159
161
  info "Following logs on #{hosts}..."
160
- info accessory.follow_logs(grep: grep)
161
- exec accessory.follow_logs(grep: grep)
162
+ info accessory.follow_logs(grep: grep, grep_options: grep_options)
163
+ exec accessory.follow_logs(grep: grep, grep_options: grep_options)
162
164
  end
163
165
  else
164
166
  since = options[:since]
165
167
  lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set
166
168
 
167
169
  on(hosts) do
168
- puts capture_with_info(*accessory.logs(since: since, lines: lines, grep: grep))
170
+ puts capture_with_info(*accessory.logs(since: since, lines: lines, grep: grep, grep_options: grep_options))
169
171
  end
170
172
  end
171
173
  end
data/lib/kamal/cli/app.rb CHANGED
@@ -166,12 +166,15 @@ class Kamal::Cli::App < Kamal::Cli::Base
166
166
  option :since, aliases: "-s", desc: "Show lines since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)"
167
167
  option :lines, type: :numeric, aliases: "-n", desc: "Number of lines to show from each server"
168
168
  option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)"
169
+ option :grep_options, aliases: "-o", desc: "Additional options supplied to grep"
169
170
  option :follow, aliases: "-f", desc: "Follow log on primary server (or specific host set by --hosts)"
170
171
  def logs
171
172
  # FIXME: Catch when app containers aren't running
172
173
 
173
174
  grep = options[:grep]
175
+ grep_options = options[:grep_options]
174
176
  since = options[:since]
177
+
175
178
  if options[:follow]
176
179
  lines = options[:lines].presence || ((since || grep) ? nil : 10) # Default to 10 lines if since or grep isn't set
177
180
 
@@ -182,8 +185,8 @@ class Kamal::Cli::App < Kamal::Cli::Base
182
185
  role = KAMAL.roles_on(KAMAL.primary_host).first
183
186
 
184
187
  app = KAMAL.app(role: role, host: host)
185
- info app.follow_logs(host: KAMAL.primary_host, lines: lines, grep: grep)
186
- exec app.follow_logs(host: KAMAL.primary_host, lines: lines, grep: grep)
188
+ info app.follow_logs(host: KAMAL.primary_host, lines: lines, grep: grep, grep_options: grep_options)
189
+ exec app.follow_logs(host: KAMAL.primary_host, lines: lines, grep: grep, grep_options: grep_options)
187
190
  end
188
191
  else
189
192
  lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set
@@ -193,7 +196,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
193
196
 
194
197
  roles.each do |role|
195
198
  begin
196
- puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).logs(since: since, lines: lines, grep: grep))
199
+ puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).logs(since: since, lines: lines, grep: grep, grep_options: grep_options))
197
200
  rescue SSHKit::Command::Failed
198
201
  puts_by_host host, "Nothing found"
199
202
  end
@@ -35,22 +35,25 @@ class Kamal::Cli::Build < Kamal::Cli::Base
35
35
 
36
36
  run_locally do
37
37
  begin
38
- KAMAL.with_verbosity(:debug) do
39
- Dir.chdir(KAMAL.config.builder.build_directory) { execute *push }
38
+ context_hosts = capture_with_info(*KAMAL.builder.context_hosts).split("\n")
39
+
40
+ if context_hosts != KAMAL.builder.config_context_hosts
41
+ warn "Context hosts have changed, so re-creating builder, was: #{context_hosts.join(", ")}], now: #{KAMAL.builder.config_context_hosts.join(", ")}"
42
+ cli.remove
43
+ cli.create
40
44
  end
41
45
  rescue SSHKit::Command::Failed => e
42
- if e.message =~ /(no builder)|(no such file or directory)/
43
- warn "Missing compatible builder, so creating a new one first"
44
-
45
- if cli.create
46
- KAMAL.with_verbosity(:debug) do
47
- Dir.chdir(KAMAL.config.builder.build_directory) { execute *push }
48
- end
49
- end
46
+ warn "Missing compatible builder, so creating a new one first"
47
+ if e.message =~ /(context not found|no builder)/
48
+ cli.create
50
49
  else
51
50
  raise
52
51
  end
53
52
  end
53
+
54
+ KAMAL.with_verbosity(:debug) do
55
+ Dir.chdir(KAMAL.config.builder.build_directory) { execute *push }
56
+ end
54
57
  end
55
58
  end
56
59
 
@@ -6,7 +6,7 @@ module Kamal::Cli::Healthcheck::Poller
6
6
 
7
7
  def wait_for_healthy(pause_after_ready: false, &block)
8
8
  attempt = 1
9
- max_attempts = KAMAL.config.healthcheck["max_attempts"]
9
+ max_attempts = KAMAL.config.healthcheck.max_attempts
10
10
 
11
11
  begin
12
12
  case status = block.call
@@ -33,7 +33,7 @@ module Kamal::Cli::Healthcheck::Poller
33
33
 
34
34
  def wait_for_unhealthy(pause_after_ready: false, &block)
35
35
  attempt = 1
36
- max_attempts = KAMAL.config.healthcheck["max_attempts"]
36
+ max_attempts = KAMAL.config.healthcheck.max_attempts
37
37
 
38
38
  begin
39
39
  case status = block.call
@@ -25,7 +25,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
25
25
  invoke_options = deploy_options
26
26
 
27
27
  say "Log into image registry...", :magenta
28
- invoke "kamal:cli:registry:login", [], invoke_options
28
+ invoke "kamal:cli:registry:login", [], invoke_options.merge(skip_local: options[:skip_push])
29
29
 
30
30
  if options[:skip_push]
31
31
  say "Pull app image...", :magenta
@@ -126,6 +126,18 @@ class Kamal::Cli::Main < Kamal::Cli::Base
126
126
  end
127
127
  end
128
128
 
129
+ desc "docs", "Show Kamal documentation for configuration setting"
130
+ def docs(section = nil)
131
+ case section
132
+ when NilClass
133
+ puts Kamal::Configuration.validation_doc
134
+ else
135
+ puts Kamal::Configuration.const_get(section.titlecase.to_sym).validation_doc
136
+ end
137
+ rescue NameError
138
+ puts "No documentation found for #{section}"
139
+ end
140
+
129
141
  desc "init", "Create config stub in config/deploy.yml and env stub in .env"
130
142
  option :bundle, type: :boolean, default: false, desc: "Add Kamal to the Gemfile and create a bin/kamal binstub"
131
143
  def init
@@ -197,7 +209,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
197
209
  invoke "kamal:cli:traefik:remove", [], options.without(:confirmed)
198
210
  invoke "kamal:cli:app:remove", [], options.without(:confirmed)
199
211
  invoke "kamal:cli:accessory:remove", [ "all" ], options
200
- invoke "kamal:cli:registry:logout", [], options.without(:confirmed)
212
+ invoke "kamal:cli:registry:logout", [], options.without(:confirmed).merge(skip_local: true)
201
213
  end
202
214
  end
203
215
  end
@@ -1,18 +1,17 @@
1
1
  class Kamal::Cli::Registry < Kamal::Cli::Base
2
2
  desc "login", "Log in to registry locally and remotely"
3
+ option :skip_local, aliases: "-L", type: :boolean, default: false, desc: "Skip local login"
4
+ option :skip_remote, aliases: "-R", type: :boolean, default: false, desc: "Skip remote login"
3
5
  def login
4
- run_locally { execute *KAMAL.registry.login }
5
- on(KAMAL.hosts) { execute *KAMAL.registry.login }
6
- # FIXME: This rescue needed?
7
- rescue ArgumentError => e
8
- puts e.message
6
+ run_locally { execute *KAMAL.registry.login } unless options[:skip_local]
7
+ on(KAMAL.hosts) { execute *KAMAL.registry.login } unless options[:skip_remote]
9
8
  end
10
9
 
11
- desc "logout", "Log out of registry remotely"
10
+ desc "logout", "Log out of registry locally and remotely"
11
+ option :skip_local, aliases: "-L", type: :boolean, default: false, desc: "Skip local login"
12
+ option :skip_remote, aliases: "-R", type: :boolean, default: false, desc: "Skip remote login"
12
13
  def logout
13
- on(KAMAL.hosts) { execute *KAMAL.registry.logout }
14
- # FIXME: This rescue needed?
15
- rescue ArgumentError => e
16
- puts e.message
14
+ run_locally { execute *KAMAL.registry.logout } unless options[:skip_local]
15
+ on(KAMAL.hosts) { execute *KAMAL.registry.logout } unless options[:skip_remote]
17
16
  end
18
17
  end
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/bin/sh
2
2
 
3
3
  # A sample docker-setup hook
4
4
  #
@@ -69,22 +69,24 @@ class Kamal::Cli::Traefik < Kamal::Cli::Base
69
69
  option :since, aliases: "-s", desc: "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)"
70
70
  option :lines, type: :numeric, aliases: "-n", desc: "Number of log lines to pull from each server"
71
71
  option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)"
72
+ option :grep_options, aliases: "-o", desc: "Additional options supplied to grep"
72
73
  option :follow, aliases: "-f", desc: "Follow logs on primary server (or specific host set by --hosts)"
73
74
  def logs
74
75
  grep = options[:grep]
76
+ grep_options = options[:grep_options]
75
77
 
76
78
  if options[:follow]
77
79
  run_locally do
78
80
  info "Following logs on #{KAMAL.primary_host}..."
79
- info KAMAL.traefik.follow_logs(host: KAMAL.primary_host, grep: grep)
80
- exec KAMAL.traefik.follow_logs(host: KAMAL.primary_host, grep: grep)
81
+ info KAMAL.traefik.follow_logs(host: KAMAL.primary_host, grep: grep, grep_options: grep_options)
82
+ exec KAMAL.traefik.follow_logs(host: KAMAL.primary_host, grep: grep, grep_options: grep_options)
81
83
  end
82
84
  else
83
85
  since = options[:since]
84
86
  lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set
85
87
 
86
88
  on(KAMAL.traefik_hosts) do |host|
87
- puts_by_host host, capture(*KAMAL.traefik.logs(since: since, lines: lines, grep: grep)), type: "Traefik"
89
+ puts_by_host host, capture(*KAMAL.traefik.logs(since: since, lines: lines, grep: grep, grep_options: grep_options)), type: "Traefik"
88
90
  end
89
91
  end
90
92
  end
data/lib/kamal/cli.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Kamal::Cli
2
- class LockError < StandardError; end
3
2
  class HookError < StandardError; end
3
+ class LockError < StandardError; end
4
4
  end
5
5
 
6
6
  # SSHKit uses instance eval, so we need a global const for ergonomics
@@ -36,17 +36,17 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
36
36
  end
37
37
 
38
38
 
39
- def logs(since: nil, lines: nil, grep: nil)
39
+ def logs(since: nil, lines: nil, grep: nil, grep_options: nil)
40
40
  pipe \
41
41
  docker(:logs, service_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), "--timestamps", "2>&1"),
42
- ("grep '#{grep}'" if grep)
42
+ ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep)
43
43
  end
44
44
 
45
- def follow_logs(grep: nil)
45
+ def follow_logs(grep: nil, grep_options: nil)
46
46
  run_over_ssh \
47
47
  pipe \
48
48
  docker(:logs, service_name, "--timestamps", "--tail", "10", "--follow", "2>&1"),
49
- (%(grep "#{grep}") if grep)
49
+ (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
50
50
  end
51
51
 
52
52
 
@@ -1,17 +1,17 @@
1
1
  module Kamal::Commands::App::Logging
2
- def logs(version: nil, since: nil, lines: nil, grep: nil)
2
+ def logs(version: nil, since: nil, lines: nil, grep: nil, grep_options: nil)
3
3
  pipe \
4
4
  version ? container_id_for_version(version) : current_running_container_id,
5
5
  "xargs docker logs#{" --since #{since}" if since}#{" --tail #{lines}" if lines} 2>&1",
6
- ("grep '#{grep}'" if grep)
6
+ ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep)
7
7
  end
8
8
 
9
- def follow_logs(host:, lines: nil, grep: nil)
9
+ def follow_logs(host:, lines: nil, grep: nil, grep_options: nil)
10
10
  run_over_ssh \
11
11
  pipe(
12
12
  current_running_container_id,
13
13
  "xargs docker logs --timestamps#{" --tail #{lines}" if lines} --follow 2>&1",
14
- (%(grep "#{grep}") if grep)
14
+ (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
15
15
  ),
16
16
  host: host
17
17
  end
@@ -2,6 +2,8 @@
2
2
  class Kamal::Commands::Builder::Base < Kamal::Commands::Base
3
3
  class BuilderError < StandardError; end
4
4
 
5
+ ENDPOINT_DOCKER_HOST_INSPECT = "'{{.Endpoints.docker.Host}}'"
6
+
5
7
  delegate :argumentize, to: Kamal::Utils
6
8
  delegate :args, :secrets, :dockerfile, :target, :local_arch, :local_host, :remote_arch, :remote_host, :cache_from, :cache_to, :ssh, to: :builder_config
7
9
 
@@ -30,6 +32,13 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
30
32
  )
31
33
  end
32
34
 
35
+ def context_hosts
36
+ :true
37
+ end
38
+
39
+ def config_context_hosts
40
+ []
41
+ end
33
42
 
34
43
  private
35
44
  def build_tags
@@ -74,4 +83,8 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
74
83
  def builder_config
75
84
  config.builder
76
85
  end
86
+
87
+ def context_host(builder_name)
88
+ docker :context, :inspect, builder_name, "--format", ENDPOINT_DOCKER_HOST_INSPECT
89
+ end
77
90
  end
@@ -12,6 +12,16 @@ class Kamal::Commands::Builder::Multiarch::Remote < Kamal::Commands::Builder::Mu
12
12
  super
13
13
  end
14
14
 
15
+ def context_hosts
16
+ chain \
17
+ context_host(builder_name_with_arch(local_arch)),
18
+ context_host(builder_name_with_arch(remote_arch))
19
+ end
20
+
21
+ def config_context_hosts
22
+ [ local_host, remote_host ].compact
23
+ end
24
+
15
25
  private
16
26
  def builder_name
17
27
  super + "-remote"
@@ -22,6 +22,10 @@ class Kamal::Commands::Builder::Multiarch < Kamal::Commands::Builder::Base
22
22
  build_context
23
23
  end
24
24
 
25
+ def context_hosts
26
+ docker :buildx, :inspect, builder_name, "> /dev/null"
27
+ end
28
+
25
29
  private
26
30
  def builder_name
27
31
  "kamal-#{config.service}-multiarch"
@@ -1,6 +1,6 @@
1
1
  class Kamal::Commands::Builder::Native::Cached < Kamal::Commands::Builder::Native
2
2
  def create
3
- docker :buildx, :create, "--use", "--driver=docker-container"
3
+ docker :buildx, :create, "--name", builder_name, "--use", "--driver=docker-container"
4
4
  end
5
5
 
6
6
  def remove
@@ -13,4 +13,13 @@ class Kamal::Commands::Builder::Native::Cached < Kamal::Commands::Builder::Nativ
13
13
  *build_options,
14
14
  build_context
15
15
  end
16
+
17
+ def context_hosts
18
+ docker :buildx, :inspect, builder_name, "> /dev/null"
19
+ end
20
+
21
+ private
22
+ def builder_name
23
+ "kamal-#{config.service}-native-cached"
24
+ end
16
25
  end
@@ -26,6 +26,14 @@ class Kamal::Commands::Builder::Native::Remote < Kamal::Commands::Builder::Nativ
26
26
  build_context
27
27
  end
28
28
 
29
+ def context_hosts
30
+ context_host(builder_name_with_arch)
31
+ end
32
+
33
+ def config_context_hosts
34
+ [ remote_host ]
35
+ end
36
+
29
37
 
30
38
  private
31
39
  def builder_name
@@ -1,7 +1,8 @@
1
1
  require "active_support/core_ext/string/filters"
2
2
 
3
3
  class Kamal::Commands::Builder < Kamal::Commands::Base
4
- delegate :create, :remove, :push, :clean, :pull, :info, :validate_image, to: :target
4
+ delegate :create, :remove, :push, :clean, :pull, :info, :context_hosts, :config_context_hosts, :validate_image,
5
+ to: :target
5
6
 
6
7
  include Clone
7
8
 
@@ -10,17 +11,22 @@ class Kamal::Commands::Builder < Kamal::Commands::Base
10
11
  end
11
12
 
12
13
  def target
13
- case
14
- when !config.builder.multiarch? && !config.builder.cached?
15
- native
16
- when !config.builder.multiarch? && config.builder.cached?
17
- native_cached
18
- when config.builder.local? && config.builder.remote?
19
- multiarch_remote
20
- when config.builder.remote?
21
- native_remote
14
+ if config.builder.multiarch?
15
+ if config.builder.remote?
16
+ if config.builder.local?
17
+ multiarch_remote
18
+ else
19
+ native_remote
20
+ end
21
+ else
22
+ multiarch
23
+ end
22
24
  else
23
- multiarch
25
+ if config.builder.cached?
26
+ native_cached
27
+ else
28
+ native
29
+ end
24
30
  end
25
31
  end
26
32
 
@@ -3,21 +3,12 @@ class Kamal::Commands::Registry < Kamal::Commands::Base
3
3
 
4
4
  def login
5
5
  docker :login,
6
- registry["server"],
7
- "-u", sensitive(Kamal::Utils.escape_shell_value(lookup("username"))),
8
- "-p", sensitive(Kamal::Utils.escape_shell_value(lookup("password")))
6
+ registry.server,
7
+ "-u", sensitive(Kamal::Utils.escape_shell_value(registry.username)),
8
+ "-p", sensitive(Kamal::Utils.escape_shell_value(registry.password))
9
9
  end
10
10
 
11
11
  def logout
12
- docker :logout, registry["server"]
12
+ docker :logout, registry.server
13
13
  end
14
-
15
- private
16
- def lookup(key)
17
- if registry[key].is_a?(Array)
18
- ENV.fetch(registry[key].first).dup
19
- else
20
- registry[key]
21
- end
22
- end
23
14
  end
@@ -1,19 +1,6 @@
1
1
  class Kamal::Commands::Traefik < Kamal::Commands::Base
2
2
  delegate :argumentize, :optionize, to: Kamal::Utils
3
-
4
- DEFAULT_IMAGE = "traefik:v2.10"
5
- CONTAINER_PORT = 80
6
- DEFAULT_ARGS = {
7
- "log.level" => "DEBUG"
8
- }
9
- DEFAULT_LABELS = {
10
- # These ensure we serve a 502 rather than a 404 if no containers are available
11
- "traefik.http.routers.catchall.entryPoints" => "http",
12
- "traefik.http.routers.catchall.rule" => "PathPrefix(`/`)",
13
- "traefik.http.routers.catchall.service" => "unavailable",
14
- "traefik.http.routers.catchall.priority" => 1,
15
- "traefik.http.services.unavailable.loadbalancer.server.port" => "0"
16
- }
3
+ delegate :port, :publish?, :labels, :env, :image, :options, :args, to: :"config.traefik"
17
4
 
18
5
  def run
19
6
  docker :run, "--name traefik",
@@ -46,16 +33,16 @@ class Kamal::Commands::Traefik < Kamal::Commands::Base
46
33
  docker :ps, "--filter", "name=^traefik$"
47
34
  end
48
35
 
49
- def logs(since: nil, lines: nil, grep: nil)
36
+ def logs(since: nil, lines: nil, grep: nil, grep_options: nil)
50
37
  pipe \
51
38
  docker(:logs, "traefik", (" --since #{since}" if since), (" --tail #{lines}" if lines), "--timestamps", "2>&1"),
52
- ("grep '#{grep}'" if grep)
39
+ ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep)
53
40
  end
54
41
 
55
- def follow_logs(host:, grep: nil)
42
+ def follow_logs(host:, grep: nil, grep_options: nil)
56
43
  run_over_ssh pipe(
57
44
  docker(:logs, "traefik", "--timestamps", "--tail", "10", "--follow", "2>&1"),
58
- (%(grep "#{grep}") if grep)
45
+ (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
59
46
  ).join(" "), host: host
60
47
  end
61
48
 
@@ -67,16 +54,6 @@ class Kamal::Commands::Traefik < Kamal::Commands::Base
67
54
  docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=Traefik"
68
55
  end
69
56
 
70
- def port
71
- "#{host_port}:#{CONTAINER_PORT}"
72
- end
73
-
74
- def env
75
- Kamal::Configuration::Env.from_config \
76
- config: config.traefik.fetch("env", {}),
77
- secrets_file: File.join(config.host_env_directory, "traefik", "traefik.env")
78
- end
79
-
80
57
  def make_env_directory
81
58
  make_directory(env.secrets_directory)
82
59
  end
@@ -87,7 +64,7 @@ class Kamal::Commands::Traefik < Kamal::Commands::Base
87
64
 
88
65
  private
89
66
  def publish_args
90
- argumentize "--publish", port unless config.traefik["publish"] == false
67
+ argumentize "--publish", port if publish?
91
68
  end
92
69
 
93
70
  def label_args
@@ -98,27 +75,11 @@ class Kamal::Commands::Traefik < Kamal::Commands::Base
98
75
  env.args
99
76
  end
100
77
 
101
- def labels
102
- DEFAULT_LABELS.merge(config.traefik["labels"] || {})
103
- end
104
-
105
- def image
106
- config.traefik.fetch("image") { DEFAULT_IMAGE }
107
- end
108
-
109
78
  def docker_options_args
110
- optionize(config.traefik["options"] || {})
79
+ optionize(options)
111
80
  end
112
81
 
113
82
  def cmd_option_args
114
- if args = config.traefik["args"]
115
- optionize DEFAULT_ARGS.merge(args), with: "="
116
- else
117
- optionize DEFAULT_ARGS, with: "="
118
- end
119
- end
120
-
121
- def host_port
122
- config.traefik["host_port"] || CONTAINER_PORT
83
+ optionize args, with: "="
123
84
  end
124
85
  end