kamal 1.5.2 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kamal/cli/accessory.rb +25 -21
- data/lib/kamal/cli/app/boot.rb +70 -18
- data/lib/kamal/cli/app/prepare_assets.rb +1 -1
- data/lib/kamal/cli/app.rb +57 -47
- data/lib/kamal/cli/base.rb +26 -28
- data/lib/kamal/cli/build/clone.rb +61 -0
- data/lib/kamal/cli/build.rb +58 -50
- data/lib/kamal/cli/env.rb +5 -5
- data/lib/kamal/cli/healthcheck/barrier.rb +31 -0
- data/lib/kamal/cli/healthcheck/error.rb +2 -0
- data/lib/kamal/cli/healthcheck/poller.rb +4 -5
- data/lib/kamal/cli/main.rb +36 -43
- data/lib/kamal/cli/prune.rb +3 -3
- data/lib/kamal/cli/server.rb +39 -15
- data/lib/kamal/cli/traefik.rb +8 -8
- data/lib/kamal/commander.rb +6 -6
- data/lib/kamal/commands/app/containers.rb +8 -0
- data/lib/kamal/commands/app/execution.rb +3 -3
- data/lib/kamal/commands/app/logging.rb +2 -2
- data/lib/kamal/commands/app.rb +6 -5
- data/lib/kamal/commands/base.rb +2 -3
- data/lib/kamal/commands/builder/base.rb +6 -12
- data/lib/kamal/commands/builder/clone.rb +28 -0
- data/lib/kamal/commands/builder/multiarch.rb +9 -9
- data/lib/kamal/commands/builder/native/cached.rb +6 -7
- data/lib/kamal/commands/builder/native/remote.rb +9 -9
- data/lib/kamal/commands/builder/native.rb +6 -7
- data/lib/kamal/commands/builder.rb +2 -0
- data/lib/kamal/configuration/builder.rb +33 -2
- data/lib/kamal/configuration/env/tag.rb +12 -0
- data/lib/kamal/configuration/env.rb +1 -1
- data/lib/kamal/configuration/role.rb +29 -6
- data/lib/kamal/configuration.rb +14 -2
- data/lib/kamal/git.rb +4 -0
- data/lib/kamal/sshkit_with_ext.rb +36 -0
- data/lib/kamal/version.rb +1 -1
- metadata +18 -9
- data/lib/kamal/cli/healthcheck.rb +0 -21
- data/lib/kamal/commands/healthcheck.rb +0 -59
data/lib/kamal/commands/app.rb
CHANGED
@@ -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, :
|
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
|
|
data/lib/kamal/commands/base.rb
CHANGED
@@ -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
|
80
|
+
def git(*args, path: nil)
|
81
|
+
[ :git, *([ "-C", path ] if path), *args.compact ]
|
83
82
|
end
|
84
83
|
|
85
84
|
def tags(**details)
|
@@ -3,7 +3,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
3
3
|
class BuilderError < StandardError; end
|
4
4
|
|
5
5
|
delegate :argumentize, to: Kamal::Utils
|
6
|
-
delegate :args, :secrets, :dockerfile, :local_arch, :local_host, :remote_arch, :remote_host, :cache_from, :cache_to, :ssh,
|
6
|
+
delegate :args, :secrets, :dockerfile, :target, :local_arch, :local_host, :remote_arch, :remote_host, :cache_from, :cache_to, :ssh, to: :builder_config
|
7
7
|
|
8
8
|
def clean
|
9
9
|
docker :image, :rm, "--force", config.absolute_image
|
@@ -13,18 +13,8 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
13
13
|
docker :pull, config.absolute_image
|
14
14
|
end
|
15
15
|
|
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
16
|
def build_options
|
27
|
-
[ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_ssh ]
|
17
|
+
[ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh ]
|
28
18
|
end
|
29
19
|
|
30
20
|
def build_context
|
@@ -73,6 +63,10 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
73
63
|
end
|
74
64
|
end
|
75
65
|
|
66
|
+
def build_target
|
67
|
+
argumentize "--target", target if target.present?
|
68
|
+
end
|
69
|
+
|
76
70
|
def build_ssh
|
77
71
|
argumentize "--ssh", ssh if ssh.present?
|
78
72
|
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
|
@@ -13,6 +13,15 @@ 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
|
+
|
16
25
|
private
|
17
26
|
def builder_name
|
18
27
|
"kamal-#{config.service}-multiarch"
|
@@ -25,13 +34,4 @@ class Kamal::Commands::Builder::Multiarch < Kamal::Commands::Builder::Base
|
|
25
34
|
"linux/amd64,linux/arm64"
|
26
35
|
end
|
27
36
|
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
37
|
end
|
@@ -7,11 +7,10 @@ class Kamal::Commands::Builder::Native::Cached < Kamal::Commands::Builder::Nativ
|
|
7
7
|
docker :buildx, :rm, builder_name
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
10
|
+
def push
|
11
|
+
docker :buildx, :build,
|
12
|
+
"--push",
|
13
|
+
*build_options,
|
14
|
+
build_context
|
15
|
+
end
|
17
16
|
end
|
@@ -17,6 +17,15 @@ 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
|
+
|
20
29
|
|
21
30
|
private
|
22
31
|
def builder_name
|
@@ -47,13 +56,4 @@ class Kamal::Commands::Builder::Native::Remote < Kamal::Commands::Builder::Nativ
|
|
47
56
|
def remove_buildx
|
48
57
|
docker :buildx, :rm, builder_name
|
49
58
|
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
59
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
@@ -3,6 +3,8 @@ require "active_support/core_ext/string/filters"
|
|
3
3
|
class Kamal::Commands::Builder < Kamal::Commands::Base
|
4
4
|
delegate :create, :remove, :push, :clean, :pull, :info, :validate_image, to: :target
|
5
5
|
|
6
|
+
include Clone
|
7
|
+
|
6
8
|
def name
|
7
9
|
target.class.to_s.remove("Kamal::Commands::Builder::").underscore.inquiry
|
8
10
|
end
|
@@ -3,6 +3,8 @@ class Kamal::Configuration::Builder
|
|
3
3
|
@options = config.raw_config.builder || {}
|
4
4
|
@image = config.image
|
5
5
|
@server = config.registry["server"]
|
6
|
+
@service = config.service
|
7
|
+
@destination = config.destination
|
6
8
|
|
7
9
|
valid?
|
8
10
|
end
|
@@ -39,8 +41,12 @@ class Kamal::Configuration::Builder
|
|
39
41
|
@options["dockerfile"] || "Dockerfile"
|
40
42
|
end
|
41
43
|
|
44
|
+
def target
|
45
|
+
@options["target"]
|
46
|
+
end
|
47
|
+
|
42
48
|
def context
|
43
|
-
@options["context"] ||
|
49
|
+
@options["context"] || "."
|
44
50
|
end
|
45
51
|
|
46
52
|
def local_arch
|
@@ -85,10 +91,23 @@ class Kamal::Configuration::Builder
|
|
85
91
|
@options["ssh"]
|
86
92
|
end
|
87
93
|
|
88
|
-
def
|
94
|
+
def git_clone?
|
89
95
|
Kamal::Git.used? && @options["context"].nil?
|
90
96
|
end
|
91
97
|
|
98
|
+
def clone_directory
|
99
|
+
@clone_directory ||= File.join Dir.tmpdir, "kamal-clones", [ @service, pwd_sha ].compact.join("-")
|
100
|
+
end
|
101
|
+
|
102
|
+
def build_directory
|
103
|
+
@build_directory ||=
|
104
|
+
if git_clone?
|
105
|
+
File.join clone_directory, repo_basename, repo_relative_pwd
|
106
|
+
else
|
107
|
+
"."
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
92
111
|
private
|
93
112
|
def valid?
|
94
113
|
if @options["cache"] && @options["cache"]["type"]
|
@@ -119,4 +138,16 @@ class Kamal::Configuration::Builder
|
|
119
138
|
def cache_to_config_for_registry
|
120
139
|
[ "type=registry", @options["cache"]&.fetch("options", nil), "ref=#{cache_image_ref}" ].compact.join(",")
|
121
140
|
end
|
141
|
+
|
142
|
+
def repo_basename
|
143
|
+
File.basename(Kamal::Git.root)
|
144
|
+
end
|
145
|
+
|
146
|
+
def repo_relative_pwd
|
147
|
+
Dir.pwd.delete_prefix(Kamal::Git.root)
|
148
|
+
end
|
149
|
+
|
150
|
+
def pwd_sha
|
151
|
+
Digest::SHA256.hexdigest(Dir.pwd)[0..12]
|
152
|
+
end
|
122
153
|
end
|
@@ -4,7 +4,7 @@ class Kamal::Configuration::Env
|
|
4
4
|
|
5
5
|
def self.from_config(config:, secrets_file: nil)
|
6
6
|
secrets_keys = config.fetch("secret", [])
|
7
|
-
clear = config.fetch("clear", config.key?("secret") ? {} : config)
|
7
|
+
clear = config.fetch("clear", config.key?("secret") || config.key?("tags") ? {} : config)
|
8
8
|
|
9
9
|
new clear: clear, secrets_keys: secrets_keys, secrets_file: secrets_file
|
10
10
|
end
|
@@ -7,6 +7,7 @@ class Kamal::Configuration::Role
|
|
7
7
|
|
8
8
|
def initialize(name, config:)
|
9
9
|
@name, @config = name.inquiry, config
|
10
|
+
@tagged_hosts ||= extract_tagged_hosts_from_config
|
10
11
|
end
|
11
12
|
|
12
13
|
def primary_host
|
@@ -14,7 +15,11 @@ class Kamal::Configuration::Role
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def hosts
|
17
|
-
|
18
|
+
tagged_hosts.keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def env_tags(host)
|
22
|
+
tagged_hosts.fetch(host).collect { |tag| config.env_tag(tag) }
|
18
23
|
end
|
19
24
|
|
20
25
|
def cmd
|
@@ -50,12 +55,13 @@ class Kamal::Configuration::Role
|
|
50
55
|
end
|
51
56
|
|
52
57
|
|
53
|
-
def env
|
54
|
-
@
|
58
|
+
def env(host)
|
59
|
+
@envs ||= {}
|
60
|
+
@envs[host] ||= [ base_env, specialized_env, *env_tags(host).map(&:env) ].reduce(:merge)
|
55
61
|
end
|
56
62
|
|
57
|
-
def env_args
|
58
|
-
env.args
|
63
|
+
def env_args(host)
|
64
|
+
env(host).args
|
59
65
|
end
|
60
66
|
|
61
67
|
def asset_volume_args
|
@@ -164,7 +170,24 @@ class Kamal::Configuration::Role
|
|
164
170
|
end
|
165
171
|
|
166
172
|
private
|
167
|
-
attr_accessor :config
|
173
|
+
attr_accessor :config, :tagged_hosts
|
174
|
+
|
175
|
+
def extract_tagged_hosts_from_config
|
176
|
+
{}.tap do |tagged_hosts|
|
177
|
+
extract_hosts_from_config.map do |host_config|
|
178
|
+
if host_config.is_a?(Hash)
|
179
|
+
raise ArgumentError, "Multiple hosts found: #{host_config.inspect}" unless host_config.size == 1
|
180
|
+
|
181
|
+
host, tags = host_config.first
|
182
|
+
tagged_hosts[host] = Array(tags)
|
183
|
+
elsif host_config.is_a?(String) || host_config.is_a?(Symbol)
|
184
|
+
tagged_hosts[host_config] = []
|
185
|
+
else
|
186
|
+
raise ArgumentError, "Invalid host config: #{host_config.inspect}"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
168
191
|
|
169
192
|
def extract_hosts_from_config
|
170
193
|
if config.servers.is_a?(Array)
|
data/lib/kamal/configuration.rb
CHANGED
@@ -188,7 +188,7 @@ class Kamal::Configuration
|
|
188
188
|
|
189
189
|
|
190
190
|
def healthcheck
|
191
|
-
{ "path" => "/up", "port" => 3000, "max_attempts" => 7, "
|
191
|
+
{ "path" => "/up", "port" => 3000, "max_attempts" => 7, "cord" => "/tmp/kamal-cord", "log_lines" => 50 }.merge(raw_config.healthcheck || {})
|
192
192
|
end
|
193
193
|
|
194
194
|
def healthcheck_service
|
@@ -233,6 +233,18 @@ class Kamal::Configuration
|
|
233
233
|
raw_config.env || {}
|
234
234
|
end
|
235
235
|
|
236
|
+
def env_tags
|
237
|
+
@env_tags ||= if (tags = raw_config.env["tags"])
|
238
|
+
tags.collect { |name, config| Kamal::Configuration::Env::Tag.new(name, config: config) }
|
239
|
+
else
|
240
|
+
[]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def env_tag(name)
|
245
|
+
env_tags.detect { |t| t.name == name.to_s }
|
246
|
+
end
|
247
|
+
|
236
248
|
|
237
249
|
def valid?
|
238
250
|
ensure_destination_if_required && ensure_required_keys_present && ensure_valid_kamal_version && ensure_retain_containers_valid && ensure_valid_service_name
|
@@ -328,7 +340,7 @@ class Kamal::Configuration
|
|
328
340
|
def git_version
|
329
341
|
@git_version ||=
|
330
342
|
if Kamal::Git.used?
|
331
|
-
if Kamal::Git.uncommitted_changes.present? && !builder.
|
343
|
+
if Kamal::Git.uncommitted_changes.present? && !builder.git_clone?
|
332
344
|
uncommitted_suffix = "_uncommitted_#{SecureRandom.hex(8)}"
|
333
345
|
end
|
334
346
|
[ Kamal::Git.revision, uncommitted_suffix ].compact.join
|
data/lib/kamal/git.rb
CHANGED
@@ -103,3 +103,39 @@ class SSHKit::Backend::Netssh
|
|
103
103
|
|
104
104
|
prepend LimitConcurrentStartsInstance
|
105
105
|
end
|
106
|
+
|
107
|
+
class SSHKit::Runner::Parallel
|
108
|
+
# SSHKit joins the threads in sequence and fails on the first error it encounters, which means that we wait threads
|
109
|
+
# before the first failure to complete but not for ones after.
|
110
|
+
#
|
111
|
+
# We'll patch it to wait for them all to complete, and to record all the threads that errored so we can see when a
|
112
|
+
# problem occurs on multiple hosts.
|
113
|
+
module CompleteAll
|
114
|
+
def execute
|
115
|
+
threads = hosts.map do |host|
|
116
|
+
Thread.new(host) do |h|
|
117
|
+
backend(h, &block).run
|
118
|
+
rescue ::StandardError => e
|
119
|
+
e2 = SSHKit::Runner::ExecuteError.new e
|
120
|
+
raise e2, "Exception while executing #{host.user ? "as #{host.user}@" : "on host "}#{host}: #{e.message}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
exceptions = []
|
125
|
+
threads.each do |t|
|
126
|
+
begin
|
127
|
+
t.join
|
128
|
+
rescue SSHKit::Runner::ExecuteError => e
|
129
|
+
exceptions << e
|
130
|
+
end
|
131
|
+
end
|
132
|
+
if exceptions.one?
|
133
|
+
raise exceptions.first
|
134
|
+
elsif exceptions.many?
|
135
|
+
raise exceptions.first, [ "Exceptions on #{exceptions.count} hosts:", exceptions.map(&:message) ].join("\n")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
prepend CompleteAll
|
141
|
+
end
|
data/lib/kamal/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kamal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -28,16 +28,22 @@ dependencies:
|
|
28
28
|
name: sshkit
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.22.2
|
34
|
+
- - "<"
|
32
35
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
36
|
+
version: '2.0'
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
|
-
- - "
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.22.2
|
44
|
+
- - "<"
|
39
45
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
46
|
+
version: '2.0'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: net-ssh
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,8 +216,10 @@ files:
|
|
210
216
|
- lib/kamal/cli/app/prepare_assets.rb
|
211
217
|
- lib/kamal/cli/base.rb
|
212
218
|
- lib/kamal/cli/build.rb
|
219
|
+
- lib/kamal/cli/build/clone.rb
|
213
220
|
- lib/kamal/cli/env.rb
|
214
|
-
- lib/kamal/cli/healthcheck.rb
|
221
|
+
- lib/kamal/cli/healthcheck/barrier.rb
|
222
|
+
- lib/kamal/cli/healthcheck/error.rb
|
215
223
|
- lib/kamal/cli/healthcheck/poller.rb
|
216
224
|
- lib/kamal/cli/lock.rb
|
217
225
|
- lib/kamal/cli/main.rb
|
@@ -243,13 +251,13 @@ files:
|
|
243
251
|
- lib/kamal/commands/base.rb
|
244
252
|
- lib/kamal/commands/builder.rb
|
245
253
|
- lib/kamal/commands/builder/base.rb
|
254
|
+
- lib/kamal/commands/builder/clone.rb
|
246
255
|
- lib/kamal/commands/builder/multiarch.rb
|
247
256
|
- lib/kamal/commands/builder/multiarch/remote.rb
|
248
257
|
- lib/kamal/commands/builder/native.rb
|
249
258
|
- lib/kamal/commands/builder/native/cached.rb
|
250
259
|
- lib/kamal/commands/builder/native/remote.rb
|
251
260
|
- lib/kamal/commands/docker.rb
|
252
|
-
- lib/kamal/commands/healthcheck.rb
|
253
261
|
- lib/kamal/commands/hook.rb
|
254
262
|
- lib/kamal/commands/lock.rb
|
255
263
|
- lib/kamal/commands/prune.rb
|
@@ -261,6 +269,7 @@ files:
|
|
261
269
|
- lib/kamal/configuration/boot.rb
|
262
270
|
- lib/kamal/configuration/builder.rb
|
263
271
|
- lib/kamal/configuration/env.rb
|
272
|
+
- lib/kamal/configuration/env/tag.rb
|
264
273
|
- lib/kamal/configuration/role.rb
|
265
274
|
- lib/kamal/configuration/ssh.rb
|
266
275
|
- lib/kamal/configuration/sshkit.rb
|
@@ -291,7 +300,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
291
300
|
- !ruby/object:Gem::Version
|
292
301
|
version: '0'
|
293
302
|
requirements: []
|
294
|
-
rubygems_version: 3.5.
|
303
|
+
rubygems_version: 3.5.10
|
295
304
|
signing_key:
|
296
305
|
specification_version: 4
|
297
306
|
summary: Deploy web apps in containers to servers running Docker with zero downtime.
|
@@ -1,21 +0,0 @@
|
|
1
|
-
class Kamal::Cli::Healthcheck < Kamal::Cli::Base
|
2
|
-
default_command :perform
|
3
|
-
|
4
|
-
desc "perform", "Health check current app version"
|
5
|
-
def perform
|
6
|
-
raise "The primary host is not configured to run Traefik" unless KAMAL.config.role(KAMAL.config.primary_role).running_traefik?
|
7
|
-
on(KAMAL.primary_host) do
|
8
|
-
begin
|
9
|
-
execute *KAMAL.healthcheck.run
|
10
|
-
Poller.wait_for_healthy { capture_with_info(*KAMAL.healthcheck.status) }
|
11
|
-
rescue Poller::HealthcheckError => e
|
12
|
-
error capture_with_info(*KAMAL.healthcheck.logs)
|
13
|
-
error capture_with_pretty_json(*KAMAL.healthcheck.container_health_log)
|
14
|
-
raise
|
15
|
-
ensure
|
16
|
-
execute *KAMAL.healthcheck.stop, raise_on_non_zero_exit: false
|
17
|
-
execute *KAMAL.healthcheck.remove, raise_on_non_zero_exit: false
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
class Kamal::Commands::Healthcheck < Kamal::Commands::Base
|
2
|
-
def run
|
3
|
-
primary = config.role(config.primary_role)
|
4
|
-
|
5
|
-
docker :run,
|
6
|
-
"--detach",
|
7
|
-
"--name", container_name_with_version,
|
8
|
-
"--publish", "#{exposed_port}:#{config.healthcheck["port"]}",
|
9
|
-
"--label", "service=#{config.healthcheck_service}",
|
10
|
-
"-e", "KAMAL_CONTAINER_NAME=\"#{config.healthcheck_service}\"",
|
11
|
-
*primary.env_args,
|
12
|
-
*primary.health_check_args(cord: false),
|
13
|
-
*config.volume_args,
|
14
|
-
*primary.option_args,
|
15
|
-
config.absolute_image,
|
16
|
-
primary.cmd
|
17
|
-
end
|
18
|
-
|
19
|
-
def status
|
20
|
-
pipe container_id, xargs(docker(:inspect, "--format", DOCKER_HEALTH_STATUS_FORMAT))
|
21
|
-
end
|
22
|
-
|
23
|
-
def container_health_log
|
24
|
-
pipe container_id, xargs(docker(:inspect, "--format", DOCKER_HEALTH_LOG_FORMAT))
|
25
|
-
end
|
26
|
-
|
27
|
-
def logs
|
28
|
-
pipe container_id, xargs(docker(:logs, "--tail", log_lines, "2>&1"))
|
29
|
-
end
|
30
|
-
|
31
|
-
def stop
|
32
|
-
pipe container_id, xargs(docker(:stop))
|
33
|
-
end
|
34
|
-
|
35
|
-
def remove
|
36
|
-
pipe container_id, xargs(docker(:container, :rm))
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
def container_name_with_version
|
41
|
-
"#{config.healthcheck_service}-#{config.version}"
|
42
|
-
end
|
43
|
-
|
44
|
-
def container_id
|
45
|
-
container_id_for(container_name: container_name_with_version)
|
46
|
-
end
|
47
|
-
|
48
|
-
def health_url
|
49
|
-
"http://localhost:#{exposed_port}#{config.healthcheck["path"]}"
|
50
|
-
end
|
51
|
-
|
52
|
-
def exposed_port
|
53
|
-
config.healthcheck["exposed_port"]
|
54
|
-
end
|
55
|
-
|
56
|
-
def log_lines
|
57
|
-
config.healthcheck["log_lines"]
|
58
|
-
end
|
59
|
-
end
|