kamal 1.5.2 → 1.6.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.
- 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
|