kamal 1.5.2 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kamal/cli/accessory.rb +30 -24
  3. data/lib/kamal/cli/app/boot.rb +70 -18
  4. data/lib/kamal/cli/app/prepare_assets.rb +1 -1
  5. data/lib/kamal/cli/app.rb +60 -47
  6. data/lib/kamal/cli/base.rb +26 -28
  7. data/lib/kamal/cli/build/clone.rb +61 -0
  8. data/lib/kamal/cli/build.rb +64 -53
  9. data/lib/kamal/cli/env.rb +5 -5
  10. data/lib/kamal/cli/healthcheck/barrier.rb +31 -0
  11. data/lib/kamal/cli/healthcheck/error.rb +2 -0
  12. data/lib/kamal/cli/healthcheck/poller.rb +6 -7
  13. data/lib/kamal/cli/main.rb +49 -44
  14. data/lib/kamal/cli/prune.rb +3 -3
  15. data/lib/kamal/cli/registry.rb +9 -10
  16. data/lib/kamal/cli/server.rb +39 -15
  17. data/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +1 -1
  18. data/lib/kamal/cli/traefik.rb +13 -11
  19. data/lib/kamal/cli.rb +1 -1
  20. data/lib/kamal/commander.rb +6 -6
  21. data/lib/kamal/commands/accessory.rb +4 -4
  22. data/lib/kamal/commands/app/containers.rb +8 -0
  23. data/lib/kamal/commands/app/execution.rb +3 -3
  24. data/lib/kamal/commands/app/logging.rb +5 -5
  25. data/lib/kamal/commands/app.rb +6 -5
  26. data/lib/kamal/commands/base.rb +2 -3
  27. data/lib/kamal/commands/builder/base.rb +19 -12
  28. data/lib/kamal/commands/builder/clone.rb +28 -0
  29. data/lib/kamal/commands/builder/multiarch/remote.rb +10 -0
  30. data/lib/kamal/commands/builder/multiarch.rb +13 -9
  31. data/lib/kamal/commands/builder/native/cached.rb +14 -6
  32. data/lib/kamal/commands/builder/native/remote.rb +17 -9
  33. data/lib/kamal/commands/builder/native.rb +6 -7
  34. data/lib/kamal/commands/builder.rb +19 -11
  35. data/lib/kamal/commands/registry.rb +4 -13
  36. data/lib/kamal/commands/traefik.rb +8 -47
  37. data/lib/kamal/configuration/accessory.rb +30 -41
  38. data/lib/kamal/configuration/boot.rb +9 -4
  39. data/lib/kamal/configuration/builder.rb +61 -30
  40. data/lib/kamal/configuration/docs/accessory.yml +90 -0
  41. data/lib/kamal/configuration/docs/boot.yml +19 -0
  42. data/lib/kamal/configuration/docs/builder.yml +107 -0
  43. data/lib/kamal/configuration/docs/configuration.yml +157 -0
  44. data/lib/kamal/configuration/docs/env.yml +72 -0
  45. data/lib/kamal/configuration/docs/healthcheck.yml +59 -0
  46. data/lib/kamal/configuration/docs/logging.yml +21 -0
  47. data/lib/kamal/configuration/docs/registry.yml +49 -0
  48. data/lib/kamal/configuration/docs/role.yml +52 -0
  49. data/lib/kamal/configuration/docs/servers.yml +27 -0
  50. data/lib/kamal/configuration/docs/ssh.yml +46 -0
  51. data/lib/kamal/configuration/docs/sshkit.yml +23 -0
  52. data/lib/kamal/configuration/docs/traefik.yml +62 -0
  53. data/lib/kamal/configuration/env/tag.rb +12 -0
  54. data/lib/kamal/configuration/env.rb +10 -14
  55. data/lib/kamal/configuration/healthcheck.rb +63 -0
  56. data/lib/kamal/configuration/logging.rb +33 -0
  57. data/lib/kamal/configuration/registry.rb +31 -0
  58. data/lib/kamal/configuration/role.rb +72 -61
  59. data/lib/kamal/configuration/servers.rb +18 -0
  60. data/lib/kamal/configuration/ssh.rb +11 -8
  61. data/lib/kamal/configuration/sshkit.rb +9 -7
  62. data/lib/kamal/configuration/traefik.rb +60 -0
  63. data/lib/kamal/configuration/validation.rb +27 -0
  64. data/lib/kamal/configuration/validator/accessory.rb +9 -0
  65. data/lib/kamal/configuration/validator/builder.rb +9 -0
  66. data/lib/kamal/configuration/validator/env.rb +54 -0
  67. data/lib/kamal/configuration/validator/registry.rb +25 -0
  68. data/lib/kamal/configuration/validator/role.rb +11 -0
  69. data/lib/kamal/configuration/validator/servers.rb +7 -0
  70. data/lib/kamal/configuration/validator.rb +140 -0
  71. data/lib/kamal/configuration.rb +50 -63
  72. data/lib/kamal/git.rb +4 -0
  73. data/lib/kamal/sshkit_with_ext.rb +36 -0
  74. data/lib/kamal/version.rb +1 -1
  75. data/lib/kamal.rb +2 -0
  76. metadata +64 -9
  77. data/lib/kamal/cli/healthcheck.rb +0 -21
  78. data/lib/kamal/commands/healthcheck.rb +0 -59
@@ -1,7 +1,7 @@
1
1
  class Kamal::Cli::Traefik < Kamal::Cli::Base
2
2
  desc "boot", "Boot Traefik on servers"
3
3
  def boot
4
- mutating do
4
+ with_lock do
5
5
  on(KAMAL.traefik_hosts) do
6
6
  execute *KAMAL.registry.login
7
7
  execute *KAMAL.traefik.start_or_run
@@ -14,7 +14,7 @@ class Kamal::Cli::Traefik < Kamal::Cli::Base
14
14
  option :confirmed, aliases: "-y", type: :boolean, default: false, desc: "Proceed without confirmation question"
15
15
  def reboot
16
16
  confirming "This will cause a brief outage on each host. Are you sure?" do
17
- mutating do
17
+ with_lock do
18
18
  host_groups = options[:rolling] ? KAMAL.traefik_hosts : [ KAMAL.traefik_hosts ]
19
19
  host_groups.each do |hosts|
20
20
  host_list = Array(hosts).join(",")
@@ -34,7 +34,7 @@ class Kamal::Cli::Traefik < Kamal::Cli::Base
34
34
 
35
35
  desc "start", "Start existing Traefik container on servers"
36
36
  def start
37
- mutating do
37
+ with_lock do
38
38
  on(KAMAL.traefik_hosts) do
39
39
  execute *KAMAL.auditor.record("Started traefik"), verbosity: :debug
40
40
  execute *KAMAL.traefik.start
@@ -44,7 +44,7 @@ class Kamal::Cli::Traefik < Kamal::Cli::Base
44
44
 
45
45
  desc "stop", "Stop existing Traefik container on servers"
46
46
  def stop
47
- mutating do
47
+ with_lock do
48
48
  on(KAMAL.traefik_hosts) do
49
49
  execute *KAMAL.auditor.record("Stopped traefik"), verbosity: :debug
50
50
  execute *KAMAL.traefik.stop, raise_on_non_zero_exit: false
@@ -54,7 +54,7 @@ class Kamal::Cli::Traefik < Kamal::Cli::Base
54
54
 
55
55
  desc "restart", "Restart existing Traefik container on servers"
56
56
  def restart
57
- mutating do
57
+ with_lock do
58
58
  stop
59
59
  start
60
60
  end
@@ -69,29 +69,31 @@ 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
91
93
 
92
94
  desc "remove", "Remove Traefik container and image from servers"
93
95
  def remove
94
- mutating do
96
+ with_lock do
95
97
  stop
96
98
  remove_container
97
99
  remove_image
@@ -100,7 +102,7 @@ class Kamal::Cli::Traefik < Kamal::Cli::Base
100
102
 
101
103
  desc "remove_container", "Remove Traefik container from servers", hide: true
102
104
  def remove_container
103
- mutating do
105
+ with_lock do
104
106
  on(KAMAL.traefik_hosts) do
105
107
  execute *KAMAL.auditor.record("Removed traefik container"), verbosity: :debug
106
108
  execute *KAMAL.traefik.remove_container
@@ -110,7 +112,7 @@ class Kamal::Cli::Traefik < Kamal::Cli::Base
110
112
 
111
113
  desc "remove_image", "Remove Traefik image from servers", hide: true
112
114
  def remove_image
113
- mutating do
115
+ with_lock do
114
116
  on(KAMAL.traefik_hosts) do
115
117
  execute *KAMAL.auditor.record("Removed traefik image"), verbosity: :debug
116
118
  execute *KAMAL.traefik.remove_image
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
@@ -2,13 +2,13 @@ require "active_support/core_ext/enumerable"
2
2
  require "active_support/core_ext/module/delegation"
3
3
 
4
4
  class Kamal::Commander
5
- attr_accessor :verbosity, :holding_lock, :hold_lock_on_error
5
+ attr_accessor :verbosity, :holding_lock, :connected
6
6
  delegate :hosts, :roles, :primary_host, :primary_role, :roles_on, :traefik_hosts, :accessory_hosts, to: :specifics
7
7
 
8
8
  def initialize
9
9
  self.verbosity = :info
10
10
  self.holding_lock = false
11
- self.hold_lock_on_error = false
11
+ self.connected = false
12
12
  @specifics = nil
13
13
  end
14
14
 
@@ -65,8 +65,8 @@ class Kamal::Commander
65
65
  end
66
66
 
67
67
 
68
- def app(role: nil)
69
- Kamal::Commands::App.new(config, role: role)
68
+ def app(role: nil, host: nil)
69
+ Kamal::Commands::App.new(config, role: role, host: host)
70
70
  end
71
71
 
72
72
  def accessory(name)
@@ -138,8 +138,8 @@ class Kamal::Commander
138
138
  self.holding_lock
139
139
  end
140
140
 
141
- def hold_lock_on_error?
142
- self.hold_lock_on_error
141
+ def connected?
142
+ self.connected
143
143
  end
144
144
 
145
145
  private
@@ -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,4 +1,6 @@
1
1
  module Kamal::Commands::App::Containers
2
+ DOCKER_HEALTH_LOG_FORMAT = "'{{json .State.Health}}'"
3
+
2
4
  def list_containers
3
5
  docker :container, :ls, "--all", *filter_args
4
6
  end
@@ -20,4 +22,10 @@ module Kamal::Commands::App::Containers
20
22
  def remove_containers
21
23
  docker :container, :prune, "--force", *filter_args
22
24
  end
25
+
26
+ def container_health_log(version:)
27
+ pipe \
28
+ container_id_for(container_name: container_name(version)),
29
+ xargs(docker(:inspect, "--format", DOCKER_HEALTH_LOG_FORMAT))
30
+ end
23
31
  end
@@ -11,7 +11,7 @@ module Kamal::Commands::App::Execution
11
11
  docker :run,
12
12
  ("-it" if interactive),
13
13
  "--rm",
14
- *role&.env_args,
14
+ *role&.env_args(host),
15
15
  *argumentize("--env", env),
16
16
  *config.volume_args,
17
17
  *role&.option_args,
@@ -19,11 +19,11 @@ module Kamal::Commands::App::Execution
19
19
  *command
20
20
  end
21
21
 
22
- def execute_in_existing_container_over_ssh(*command, host:, env:)
22
+ def execute_in_existing_container_over_ssh(*command, env:)
23
23
  run_over_ssh execute_in_existing_container(*command, interactive: true, env: env), host: host
24
24
  end
25
25
 
26
- def execute_in_new_container_over_ssh(*command, host:, env:)
26
+ def execute_in_new_container_over_ssh(*command, env:)
27
27
  run_over_ssh execute_in_new_container(*command, interactive: true, env: env), host: host
28
28
  end
29
29
  end
@@ -1,17 +1,17 @@
1
1
  module Kamal::Commands::App::Logging
2
- def logs(since: nil, lines: nil, grep: nil)
2
+ def logs(version: nil, since: nil, lines: nil, grep: nil, grep_options: nil)
3
3
  pipe \
4
- current_running_container_id,
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
@@ -3,11 +3,12 @@ class Kamal::Commands::App < Kamal::Commands::Base
3
3
 
4
4
  ACTIVE_DOCKER_STATUSES = [ :running, :restarting ]
5
5
 
6
- attr_reader :role, :role
6
+ attr_reader :role, :host
7
7
 
8
- def initialize(config, role: nil)
8
+ def initialize(config, role: nil, host: nil)
9
9
  super(config)
10
10
  @role = role
11
+ @host = host
11
12
  end
12
13
 
13
14
  def run(hostname: nil)
@@ -18,7 +19,7 @@ class Kamal::Commands::App < Kamal::Commands::Base
18
19
  *([ "--hostname", hostname ] if hostname),
19
20
  "-e", "KAMAL_CONTAINER_NAME=\"#{container_name}\"",
20
21
  "-e", "KAMAL_VERSION=\"#{config.version}\"",
21
- *role.env_args,
22
+ *role.env_args(host),
22
23
  *role.health_check_args,
23
24
  *role.logging_args,
24
25
  *config.volume_args,
@@ -70,11 +71,11 @@ class Kamal::Commands::App < Kamal::Commands::Base
70
71
 
71
72
 
72
73
  def make_env_directory
73
- make_directory role.env.secrets_directory
74
+ make_directory role.env(host).secrets_directory
74
75
  end
75
76
 
76
77
  def remove_env_file
77
- [ :rm, "-f", role.env.secrets_file ]
78
+ [ :rm, "-f", role.env(host).secrets_file ]
78
79
  end
79
80
 
80
81
 
@@ -3,7 +3,6 @@ module Kamal::Commands
3
3
  delegate :sensitive, :argumentize, to: Kamal::Utils
4
4
 
5
5
  DOCKER_HEALTH_STATUS_FORMAT = "'{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}'"
6
- DOCKER_HEALTH_LOG_FORMAT = "'{{json .State.Health}}'"
7
6
 
8
7
  attr_accessor :config
9
8
 
@@ -78,8 +77,8 @@ module Kamal::Commands
78
77
  args.compact.unshift :docker
79
78
  end
80
79
 
81
- def git(*args)
82
- args.compact.unshift :git
80
+ def git(*args, path: nil)
81
+ [ :git, *([ "-C", path ] if path), *args.compact ]
83
82
  end
84
83
 
85
84
  def tags(**details)
@@ -2,8 +2,10 @@
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
- delegate :args, :secrets, :dockerfile, :local_arch, :local_host, :remote_arch, :remote_host, :cache_from, :cache_to, :ssh, :git_archive?, to: :builder_config
8
+ delegate :args, :secrets, :dockerfile, :target, :local_arch, :local_host, :remote_arch, :remote_host, :cache_from, :cache_to, :ssh, to: :builder_config
7
9
 
8
10
  def clean
9
11
  docker :image, :rm, "--force", config.absolute_image
@@ -13,18 +15,8 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
13
15
  docker :pull, config.absolute_image
14
16
  end
15
17
 
16
- def push
17
- if git_archive?
18
- pipe \
19
- git(:archive, "--format=tar", :HEAD),
20
- build_and_push
21
- else
22
- build_and_push
23
- end
24
- end
25
-
26
18
  def build_options
27
- [ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_ssh ]
19
+ [ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh ]
28
20
  end
29
21
 
30
22
  def build_context
@@ -40,6 +32,13 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
40
32
  )
41
33
  end
42
34
 
35
+ def context_hosts
36
+ :true
37
+ end
38
+
39
+ def config_context_hosts
40
+ []
41
+ end
43
42
 
44
43
  private
45
44
  def build_tags
@@ -73,6 +72,10 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
73
72
  end
74
73
  end
75
74
 
75
+ def build_target
76
+ argumentize "--target", target if target.present?
77
+ end
78
+
76
79
  def build_ssh
77
80
  argumentize "--ssh", ssh if ssh.present?
78
81
  end
@@ -80,4 +83,8 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
80
83
  def builder_config
81
84
  config.builder
82
85
  end
86
+
87
+ def context_host(builder_name)
88
+ docker :context, :inspect, builder_name, "--format", ENDPOINT_DOCKER_HOST_INSPECT
89
+ end
83
90
  end
@@ -0,0 +1,28 @@
1
+ module Kamal::Commands::Builder::Clone
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ delegate :clone_directory, :build_directory, to: :"config.builder"
6
+ end
7
+
8
+ def clone
9
+ git :clone, Kamal::Git.root, path: clone_directory
10
+ end
11
+
12
+ def clone_reset_steps
13
+ [
14
+ git(:remote, "set-url", :origin, Kamal::Git.root, path: build_directory),
15
+ git(:fetch, :origin, path: build_directory),
16
+ git(:reset, "--hard", Kamal::Git.revision, path: build_directory),
17
+ git(:clean, "-fdx", path: build_directory)
18
+ ]
19
+ end
20
+
21
+ def clone_status
22
+ git :status, "--porcelain", path: build_directory
23
+ end
24
+
25
+ def clone_revision
26
+ git :"rev-parse", :HEAD, path: build_directory
27
+ end
28
+ 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"
@@ -13,6 +13,19 @@ class Kamal::Commands::Builder::Multiarch < Kamal::Commands::Builder::Base
13
13
  docker(:buildx, :ls)
14
14
  end
15
15
 
16
+ def push
17
+ docker :buildx, :build,
18
+ "--push",
19
+ "--platform", platform_names,
20
+ "--builder", builder_name,
21
+ *build_options,
22
+ build_context
23
+ end
24
+
25
+ def context_hosts
26
+ docker :buildx, :inspect, builder_name, "> /dev/null"
27
+ end
28
+
16
29
  private
17
30
  def builder_name
18
31
  "kamal-#{config.service}-multiarch"
@@ -25,13 +38,4 @@ class Kamal::Commands::Builder::Multiarch < Kamal::Commands::Builder::Base
25
38
  "linux/amd64,linux/arm64"
26
39
  end
27
40
  end
28
-
29
- def build_and_push
30
- docker :buildx, :build,
31
- "--push",
32
- "--platform", platform_names,
33
- "--builder", builder_name,
34
- *build_options,
35
- build_context
36
- end
37
41
  end
@@ -1,17 +1,25 @@
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
7
7
  docker :buildx, :rm, builder_name
8
8
  end
9
9
 
10
+ def push
11
+ docker :buildx, :build,
12
+ "--push",
13
+ *build_options,
14
+ build_context
15
+ end
16
+
17
+ def context_hosts
18
+ docker :buildx, :inspect, builder_name, "> /dev/null"
19
+ end
20
+
10
21
  private
11
- def build_and_push
12
- docker :buildx, :build,
13
- "--push",
14
- *build_options,
15
- build_context
22
+ def builder_name
23
+ "kamal-#{config.service}-native-cached"
16
24
  end
17
25
  end
@@ -17,6 +17,23 @@ class Kamal::Commands::Builder::Native::Remote < Kamal::Commands::Builder::Nativ
17
17
  docker(:buildx, :ls)
18
18
  end
19
19
 
20
+ def push
21
+ docker :buildx, :build,
22
+ "--push",
23
+ "--platform", platform,
24
+ "--builder", builder_name,
25
+ *build_options,
26
+ build_context
27
+ end
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
+
20
37
 
21
38
  private
22
39
  def builder_name
@@ -47,13 +64,4 @@ class Kamal::Commands::Builder::Native::Remote < Kamal::Commands::Builder::Nativ
47
64
  def remove_buildx
48
65
  docker :buildx, :rm, builder_name
49
66
  end
50
-
51
- def build_and_push
52
- docker :buildx, :build,
53
- "--push",
54
- "--platform", platform,
55
- "--builder", builder_name,
56
- *build_options,
57
- build_context
58
- end
59
67
  end
@@ -11,11 +11,10 @@ class Kamal::Commands::Builder::Native < Kamal::Commands::Builder::Base
11
11
  # No-op on native
12
12
  end
13
13
 
14
- private
15
- def build_and_push
16
- combine \
17
- docker(:build, *build_options, build_context),
18
- docker(:push, config.absolute_image),
19
- docker(:push, config.latest_image)
20
- end
14
+ def push
15
+ combine \
16
+ docker(:build, *build_options, build_context),
17
+ docker(:push, config.absolute_image),
18
+ docker(:push, config.latest_image)
19
+ end
21
20
  end
@@ -1,24 +1,32 @@
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
6
+
7
+ include Clone
5
8
 
6
9
  def name
7
10
  target.class.to_s.remove("Kamal::Commands::Builder::").underscore.inquiry
8
11
  end
9
12
 
10
13
  def target
11
- case
12
- when !config.builder.multiarch? && !config.builder.cached?
13
- native
14
- when !config.builder.multiarch? && config.builder.cached?
15
- native_cached
16
- when config.builder.local? && config.builder.remote?
17
- multiarch_remote
18
- when config.builder.remote?
19
- 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
20
24
  else
21
- multiarch
25
+ if config.builder.cached?
26
+ native_cached
27
+ else
28
+ native
29
+ end
22
30
  end
23
31
  end
24
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