dash 3.2.0 → 4.0.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/README.md +1 -1
- data/bin/dash +2 -2
- data/lib/{kamal → dash}/cli/accessory.rb +24 -24
- data/lib/dash/cli/alias/command.rb +10 -0
- data/lib/{kamal → dash}/cli/app/assets.rb +2 -2
- data/lib/{kamal → dash}/cli/app/boot.rb +16 -16
- data/lib/{kamal → dash}/cli/app/error_pages.rb +6 -6
- data/lib/{kamal → dash}/cli/app/rollout_boot.rb +6 -6
- data/lib/{kamal → dash}/cli/app/ssl_certificates.rb +3 -3
- data/lib/{kamal → dash}/cli/app.rb +87 -87
- data/lib/{kamal → dash}/cli/base.rb +72 -48
- data/lib/dash/cli/build/clone.rb +59 -0
- data/lib/{kamal → dash}/cli/build/port_forwarding.rb +1 -1
- data/lib/{kamal → dash}/cli/build.rb +45 -45
- data/lib/{kamal → dash}/cli/doctor/config_checks.rb +3 -3
- data/lib/{kamal → dash}/cli/doctor/endpoint_checks.rb +26 -8
- data/lib/{kamal → dash}/cli/doctor/host_checks.rb +22 -22
- data/lib/{kamal → dash}/cli/doctor.rb +9 -9
- data/lib/{kamal → dash}/cli/healthcheck/barrier.rb +2 -2
- data/lib/{kamal → dash}/cli/healthcheck/drift_error.rb +2 -2
- data/lib/dash/cli/healthcheck/error.rb +2 -0
- data/lib/{kamal → dash}/cli/healthcheck/poller.rb +7 -7
- data/lib/{kamal → dash}/cli/lock.rb +1 -1
- data/lib/dash/cli/main/migrate.rb +77 -0
- data/lib/{kamal → dash}/cli/main.rb +82 -71
- data/lib/{kamal → dash}/cli/proxy/drift.rb +3 -3
- data/lib/dash/cli/proxy/legacy_rename.rb +58 -0
- data/lib/{kamal → dash}/cli/proxy/loadbalancer_claim.rb +3 -3
- data/lib/{kamal → dash}/cli/proxy/loadbalancer_reboot.rb +23 -23
- data/lib/{kamal → dash}/cli/proxy/reboot.rb +21 -21
- data/lib/{kamal → dash}/cli/proxy.rb +178 -162
- data/lib/{kamal → dash}/cli/prune.rb +10 -10
- data/lib/{kamal → dash}/cli/registry.rb +11 -11
- data/lib/{kamal → dash}/cli/secrets.rb +3 -3
- data/lib/{kamal → dash}/cli/server.rb +14 -14
- data/lib/{kamal → dash}/cli/templates/deploy.yml +4 -4
- data/lib/dash/cli/templates/sample_hooks/docker-setup.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/post-app-boot.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/post-app-stop.sample +9 -0
- data/lib/dash/cli/templates/sample_hooks/post-deploy.sample +14 -0
- data/lib/dash/cli/templates/sample_hooks/post-proxy-deploy.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/pre-app-boot.sample +3 -0
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-app-stop.sample +2 -2
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-build.sample +8 -8
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-connect.sample +8 -8
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-deploy.sample +9 -9
- data/lib/dash/cli/templates/sample_hooks/pre-proxy-deploy.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/pre-proxy-reboot.sample +3 -0
- data/lib/{kamal → dash}/cli/templates/secrets +6 -6
- data/lib/{kamal → dash}/cli.rb +2 -2
- data/lib/{kamal → dash}/commander/specifics.rb +2 -2
- data/lib/{kamal → dash}/commander.rb +32 -24
- data/lib/{kamal → dash}/commands/accessory/proxy.rb +2 -2
- data/lib/{kamal → dash}/commands/accessory.rb +2 -2
- data/lib/{kamal → dash}/commands/app/assets.rb +1 -1
- data/lib/{kamal → dash}/commands/app/containers.rb +1 -1
- data/lib/{kamal → dash}/commands/app/error_pages.rb +2 -2
- data/lib/{kamal → dash}/commands/app/execution.rb +2 -2
- data/lib/{kamal → dash}/commands/app/images.rb +1 -1
- data/lib/{kamal → dash}/commands/app/logging.rb +1 -1
- data/lib/{kamal → dash}/commands/app/proxy.rb +2 -2
- data/lib/{kamal → dash}/commands/app.rb +2 -2
- data/lib/{kamal → dash}/commands/auditor.rb +3 -7
- data/lib/{kamal → dash}/commands/base.rb +39 -3
- data/lib/{kamal → dash}/commands/builder/base.rb +2 -2
- data/lib/{kamal → dash}/commands/builder/clone.rb +3 -3
- data/lib/{kamal → dash}/commands/builder/cloud.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/hybrid.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/local.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/pack.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/remote.rb +1 -1
- data/lib/{kamal → dash}/commands/builder.rb +7 -7
- data/lib/dash/commands/docker.rb +89 -0
- data/lib/{kamal → dash}/commands/hook.rb +1 -1
- data/lib/{kamal → dash}/commands/loadbalancer.rb +55 -24
- data/lib/{kamal → dash}/commands/lock.rb +3 -3
- data/lib/{kamal → dash}/commands/proxy/cert_transfer.rb +6 -6
- data/lib/dash/commands/proxy.rb +375 -0
- data/lib/{kamal → dash}/commands/prune.rb +2 -2
- data/lib/dash/commands/registry.rb +44 -0
- data/lib/{kamal → dash}/commands/server.rb +1 -5
- data/lib/dash/commands.rb +2 -0
- data/lib/{kamal → dash}/configuration/accessory.rb +13 -13
- data/lib/{kamal → dash}/configuration/alias.rb +3 -3
- data/lib/{kamal → dash}/configuration/boot.rb +2 -2
- data/lib/{kamal → dash}/configuration/builder.rb +7 -7
- data/lib/{kamal → dash}/configuration/docs/accessory.yml +3 -3
- data/lib/{kamal → dash}/configuration/docs/builder.yml +3 -3
- data/lib/{kamal → dash}/configuration/docs/configuration.yml +13 -6
- data/lib/{kamal → dash}/configuration/docs/env.yml +10 -10
- data/lib/{kamal → dash}/configuration/docs/proxy.yml +68 -45
- data/lib/{kamal → dash}/configuration/docs/registry.yml +5 -5
- data/lib/{kamal → dash}/configuration/env/tag.rb +2 -2
- data/lib/{kamal → dash}/configuration/env.rb +5 -5
- data/lib/{kamal → dash}/configuration/loadbalancer.rb +5 -5
- data/lib/{kamal → dash}/configuration/logging.rb +3 -3
- data/lib/{kamal → dash}/configuration/output.rb +4 -4
- data/lib/{kamal → dash}/configuration/proxy/acme.rb +9 -8
- data/lib/{kamal → dash}/configuration/proxy/boot.rb +9 -11
- data/lib/{kamal → dash}/configuration/proxy/run.rb +20 -20
- data/lib/{kamal → dash}/configuration/proxy.rb +51 -29
- data/lib/{kamal → dash}/configuration/registry.rb +3 -3
- data/lib/{kamal → dash}/configuration/role/healthcheck.rb +3 -3
- data/lib/{kamal → dash}/configuration/role.rb +14 -14
- data/lib/{kamal → dash}/configuration/servers.rb +4 -4
- data/lib/{kamal → dash}/configuration/ssh.rb +2 -2
- data/lib/{kamal → dash}/configuration/sshkit.rb +2 -2
- data/lib/{kamal → dash}/configuration/validation.rb +2 -2
- data/lib/{kamal → dash}/configuration/validator/accessory.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator/alias.rb +2 -2
- data/lib/{kamal → dash}/configuration/validator/builder.rb +1 -1
- data/lib/dash/configuration/validator/configuration.rb +6 -0
- data/lib/{kamal → dash}/configuration/validator/env.rb +2 -2
- data/lib/{kamal → dash}/configuration/validator/proxy.rb +31 -31
- data/lib/{kamal → dash}/configuration/validator/registry.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator/role.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator/servers.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator.rb +4 -4
- data/lib/{kamal → dash}/configuration/volume.rb +2 -2
- data/lib/{kamal → dash}/configuration.rb +47 -37
- data/lib/{kamal → dash}/docker.rb +1 -1
- data/lib/{kamal → dash}/env_file.rb +1 -1
- data/lib/{kamal → dash}/git.rb +1 -1
- data/lib/{kamal → dash}/otel_shipper.rb +3 -3
- data/lib/{kamal → dash}/output/base_logger.rb +1 -1
- data/lib/{kamal → dash}/output/file_logger.rb +1 -1
- data/lib/{kamal → dash}/output/formatter.rb +1 -1
- data/lib/{kamal → dash}/output/otel_logger.rb +3 -3
- data/lib/dash/project_directory.rb +28 -0
- data/lib/{kamal → dash}/secrets/adapters/aws_secrets_manager.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/base.rb +2 -2
- data/lib/{kamal → dash}/secrets/adapters/bitwarden.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/bitwarden_secrets_manager.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/doppler.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/enpass.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/gcp_secret_manager.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/last_pass.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/one_password.rb +2 -2
- data/lib/{kamal → dash}/secrets/adapters/passbolt.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/test.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters.rb +2 -2
- data/lib/{kamal → dash}/secrets/dotenv/inline_command_substitution.rb +2 -2
- data/lib/{kamal → dash}/secrets.rb +6 -6
- data/lib/{kamal → dash}/tags.rb +8 -3
- data/lib/{kamal → dash}/utils/sensitive.rb +1 -1
- data/lib/{kamal → dash}/utils.rb +16 -6
- data/lib/dash/version.rb +3 -0
- data/lib/{kamal.rb → dash.rb} +4 -4
- metadata +157 -154
- data/lib/kamal/cli/alias/command.rb +0 -10
- data/lib/kamal/cli/build/clone.rb +0 -59
- data/lib/kamal/cli/healthcheck/error.rb +0 -2
- data/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/post-app-boot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/post-app-stop.sample +0 -9
- data/lib/kamal/cli/templates/sample_hooks/post-deploy.sample +0 -14
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-deploy.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-app-boot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-proxy-deploy.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-proxy-reboot.sample +0 -3
- data/lib/kamal/commands/docker.rb +0 -55
- data/lib/kamal/commands/proxy.rb +0 -266
- data/lib/kamal/commands/registry.rb +0 -38
- data/lib/kamal/commands.rb +0 -2
- data/lib/kamal/configuration/validator/configuration.rb +0 -6
- data/lib/kamal/version.rb +0 -3
- /data/lib/{kamal → dash}/configuration/docs/alias.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/boot.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/logging.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/output.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/role.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/servers.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/ssh.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/sshkit.yml +0 -0
- /data/lib/{kamal → dash}/sshkit_with_ext.rb +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Proxy::Boot
|
|
2
2
|
attr_reader :config
|
|
3
|
-
delegate :argumentize, :optionize, to:
|
|
3
|
+
delegate :argumentize, :optionize, to: Dash::Utils
|
|
4
4
|
|
|
5
5
|
def initialize(config:)
|
|
6
6
|
@config = config
|
|
@@ -11,8 +11,8 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
11
11
|
|
|
12
12
|
(bind_ips || [ nil ]).map do |bind_ip|
|
|
13
13
|
bind_ip = format_bind_ip(bind_ip)
|
|
14
|
-
publish_http = [ bind_ip, http_port,
|
|
15
|
-
publish_https = [ bind_ip, https_port,
|
|
14
|
+
publish_http = [ bind_ip, http_port, Dash::Configuration::Proxy::Run::DEFAULT_HTTP_PORT ].compact.join(":")
|
|
15
|
+
publish_https = [ bind_ip, https_port, Dash::Configuration::Proxy::Run::DEFAULT_HTTPS_PORT ].compact.join(":")
|
|
16
16
|
|
|
17
17
|
argumentize "--publish", [ publish_http, publish_https ]
|
|
18
18
|
end.join(" ")
|
|
@@ -24,8 +24,8 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
24
24
|
|
|
25
25
|
def default_boot_options
|
|
26
26
|
[
|
|
27
|
-
*(publish_args(
|
|
28
|
-
*(logging_args(
|
|
27
|
+
*(publish_args(Dash::Configuration::Proxy::Run::DEFAULT_HTTP_PORT, Dash::Configuration::Proxy::Run::DEFAULT_HTTPS_PORT, nil)),
|
|
28
|
+
*(logging_args(Dash::Configuration::Proxy::Run::DEFAULT_LOG_MAX_SIZE))
|
|
29
29
|
]
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -41,10 +41,8 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
41
41
|
"#{repository_name}/#{image_name}"
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
# Stays kamal-proxy until the server-artifact rename ships a migration
|
|
45
|
-
# bridge — every deployed host has a running container by this name.
|
|
46
44
|
def container_name
|
|
47
|
-
|
|
45
|
+
Dash::Configuration::Proxy::CONTAINER_NAME
|
|
48
46
|
end
|
|
49
47
|
|
|
50
48
|
def host_directory
|
|
@@ -72,11 +70,11 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
72
70
|
end
|
|
73
71
|
|
|
74
72
|
def apps_container_directory
|
|
75
|
-
"/home/
|
|
73
|
+
"/home/dash-proxy/.apps-config"
|
|
76
74
|
end
|
|
77
75
|
|
|
78
76
|
def apps_volume
|
|
79
|
-
|
|
77
|
+
Dash::Configuration::Volume.new \
|
|
80
78
|
host_path: apps_directory,
|
|
81
79
|
container_path: apps_container_directory
|
|
82
80
|
end
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
class
|
|
2
|
-
MINIMUM_VERSION = "v1.0.0
|
|
1
|
+
class Dash::Configuration::Proxy::Run
|
|
2
|
+
MINIMUM_VERSION = "v1.1.0.0"
|
|
3
3
|
DEFAULT_HTTP_PORT = 80
|
|
4
4
|
DEFAULT_HTTPS_PORT = 443
|
|
5
5
|
DEFAULT_LOG_MAX_SIZE = "10m"
|
|
6
6
|
|
|
7
7
|
# One env file for everything the proxy must know but nothing may print:
|
|
8
8
|
# ACME DNS credentials and the cache store URL. Also referenced by
|
|
9
|
-
#
|
|
9
|
+
# Dash::Commands::Proxy#remove_proxy_secrets_file, which cleans it up when
|
|
10
10
|
# the config no longer needs it.
|
|
11
11
|
SECRETS_FILENAME = "secrets.env"
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
15
15
|
DIGEST_SCHEMA_VERSION = "v1"
|
|
16
16
|
|
|
17
17
|
attr_reader :config, :run_config
|
|
18
|
-
delegate :argumentize, :optionize, :seconds_duration, to:
|
|
18
|
+
delegate :argumentize, :optionize, :seconds_duration, to: Dash::Utils
|
|
19
19
|
|
|
20
20
|
def initialize(config, run_config:, context: "proxy/run")
|
|
21
21
|
@config = config
|
|
@@ -43,7 +43,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def acme
|
|
46
|
-
@acme ||=
|
|
46
|
+
@acme ||= Dash::Configuration::Proxy::Acme.new(acme_config: run_config["acme"], secrets: config.secrets)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def debug?
|
|
@@ -103,7 +103,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def container_name
|
|
106
|
-
"
|
|
106
|
+
"dash-proxy"
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
# Zero-downtime reboots: a minimal long-lived holder container owns the
|
|
@@ -114,14 +114,14 @@ class Kamal::Configuration::Proxy::Run
|
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
def holder_container_name
|
|
117
|
-
"
|
|
117
|
+
"dash-proxy-net"
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
def network_args
|
|
121
121
|
if port_holder?
|
|
122
122
|
[ "--network", "container:#{holder_container_name}" ]
|
|
123
123
|
else
|
|
124
|
-
[ "--network", "
|
|
124
|
+
[ "--network", "dash" ]
|
|
125
125
|
end
|
|
126
126
|
end
|
|
127
127
|
|
|
@@ -136,7 +136,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
136
136
|
end
|
|
137
137
|
|
|
138
138
|
def run_command
|
|
139
|
-
[ "
|
|
139
|
+
[ "dash-proxy", "run", *optionize(run_command_options), *acme.run_command_args ].join(" ")
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
def metrics_port
|
|
@@ -158,7 +158,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
158
158
|
.compact.merge(cache_options).merge(server_options)
|
|
159
159
|
end
|
|
160
160
|
|
|
161
|
-
# Anything
|
|
161
|
+
# Anything dash-proxy accepts that has no key of its own yet. Values are
|
|
162
162
|
# optionized as written - `true` is a bare flag, anything else takes a value -
|
|
163
163
|
# because the point of an escape hatch is that the gem holds no opinion about
|
|
164
164
|
# the flag it is forwarding.
|
|
@@ -189,12 +189,12 @@ class Kamal::Configuration::Proxy::Run
|
|
|
189
189
|
].compact
|
|
190
190
|
end
|
|
191
191
|
|
|
192
|
-
# The flag only tells
|
|
192
|
+
# The flag only tells dash-proxy where to look inside its own container, so
|
|
193
193
|
# without this mount the socket is not there and a sleeping service never
|
|
194
194
|
# wakes - which the operator sees as one hung request, not as a misconfiguration.
|
|
195
195
|
def docker_socket_args
|
|
196
196
|
if docker_socket.present?
|
|
197
|
-
|
|
197
|
+
Dash::Configuration::Volume.new(host_path: docker_socket, container_path: docker_socket).docker_args
|
|
198
198
|
end
|
|
199
199
|
end
|
|
200
200
|
|
|
@@ -212,7 +212,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
212
212
|
end
|
|
213
213
|
|
|
214
214
|
def secrets_io
|
|
215
|
-
|
|
215
|
+
Dash::EnvFile.new(acme.credentials_env.merge(cache_store_env)).to_io
|
|
216
216
|
end
|
|
217
217
|
|
|
218
218
|
def host_directory
|
|
@@ -224,11 +224,11 @@ class Kamal::Configuration::Proxy::Run
|
|
|
224
224
|
end
|
|
225
225
|
|
|
226
226
|
def apps_container_directory
|
|
227
|
-
"/home/
|
|
227
|
+
"/home/dash-proxy/.apps-config"
|
|
228
228
|
end
|
|
229
229
|
|
|
230
230
|
def apps_volume
|
|
231
|
-
|
|
231
|
+
Dash::Configuration::Volume.new \
|
|
232
232
|
host_path: apps_directory,
|
|
233
233
|
container_path: apps_container_directory
|
|
234
234
|
end
|
|
@@ -255,7 +255,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
# Whether an operator turned on PROXY protocol without saying who may speak
|
|
258
|
-
# it.
|
|
258
|
+
# it. Dash::Configuration warns about this: the header rewrites the
|
|
259
259
|
# connecting address that allow_ips and rate_limit key on, so honouring it
|
|
260
260
|
# from anywhere is a client-IP spoofing hole.
|
|
261
261
|
def proxy_protocol_unrestricted?
|
|
@@ -264,7 +264,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
264
264
|
|
|
265
265
|
private
|
|
266
266
|
# The proxy's own listeners and process-level behaviour, as opposed to the
|
|
267
|
-
# per-service deadlines in
|
|
267
|
+
# per-service deadlines in Dash::Configuration::Proxy#deploy_options. Zero
|
|
268
268
|
# disables each of the timeouts, so it is a value rather than an absence.
|
|
269
269
|
def server_options
|
|
270
270
|
{
|
|
@@ -288,14 +288,14 @@ class Kamal::Configuration::Proxy::Run
|
|
|
288
288
|
end
|
|
289
289
|
|
|
290
290
|
# A passthrough flag that a named key already emits would be optionized
|
|
291
|
-
# twice, and
|
|
291
|
+
# twice, and dash-proxy would silently take the last one. Refuse instead.
|
|
292
292
|
# Only Proxy::Run knows which flags the named keys produce, so the check
|
|
293
293
|
# cannot live in the validator with the rest.
|
|
294
294
|
def ensure_no_conflicting_flags
|
|
295
295
|
conflicts = flags.keys.map(&:to_s) & named_run_command_options.keys.map(&:to_s)
|
|
296
296
|
return true if conflicts.empty?
|
|
297
297
|
|
|
298
|
-
raise
|
|
298
|
+
raise Dash::ConfigurationError,
|
|
299
299
|
"#{@context}/flags: #{conflicts.sort.join(", ")} is already set by a named key - remove one of them"
|
|
300
300
|
end
|
|
301
301
|
|
|
@@ -303,7 +303,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
303
303
|
# than of any one service - the policy that fills the cache is per service,
|
|
304
304
|
# in proxy/cache. The store itself is deliberately absent: a store URL may
|
|
305
305
|
# embed credentials, so it travels as CACHE_STORE in the secrets env file
|
|
306
|
-
# (
|
|
306
|
+
# (dash-proxy reads it as the --cache-store default) rather than on a
|
|
307
307
|
# command line that lands in process listings and the audit log.
|
|
308
308
|
def cache_options
|
|
309
309
|
cache = run_config["cache"] || {}
|
|
@@ -1,12 +1,34 @@
|
|
|
1
|
-
class
|
|
2
|
-
include
|
|
1
|
+
class Dash::Configuration::Proxy
|
|
2
|
+
include Dash::Configuration::Validation
|
|
3
3
|
|
|
4
4
|
DEFAULT_LOG_REQUEST_HEADERS = [ "Cache-Control", "Last-Modified", "User-Agent" ]
|
|
5
|
-
CONTAINER_NAME = "
|
|
6
|
-
LOADBALANCER_CONTAINER_NAME = "
|
|
5
|
+
CONTAINER_NAME = "dash-proxy"
|
|
6
|
+
LOADBALANCER_CONTAINER_NAME = "dash-loadbalancer"
|
|
7
7
|
CLIENT_CA_FILENAME = "client-ca.pem"
|
|
8
8
|
|
|
9
|
-
#
|
|
9
|
+
# The image label the prune filters key on, set by dash-proxy's publish
|
|
10
|
+
# workflow.
|
|
11
|
+
IMAGE_TITLE = "dash-proxy"
|
|
12
|
+
LOADBALANCER_IMAGE_TITLE = "dash-loadbalancer"
|
|
13
|
+
|
|
14
|
+
NETWORK = "dash"
|
|
15
|
+
CONFIG_VOLUME = "dash-proxy-config"
|
|
16
|
+
LOADBALANCER_CONFIG_VOLUME = "dash-loadbalancer-config"
|
|
17
|
+
|
|
18
|
+
# Pre-rename names, kept only so the stage-3c migration can find what a host
|
|
19
|
+
# already has: the container to replace, the volume to copy, the network to
|
|
20
|
+
# bridge, and the image label to keep pruning by. Nothing constructs a
|
|
21
|
+
# resource with these — stage 3d deletes them.
|
|
22
|
+
LEGACY_CONTAINER_NAME = "kamal-proxy"
|
|
23
|
+
LEGACY_LOADBALANCER_CONTAINER_NAME = "kamal-loadbalancer"
|
|
24
|
+
LEGACY_HOLDER_CONTAINER_NAME = "kamal-proxy-net"
|
|
25
|
+
LEGACY_NETWORK = "kamal"
|
|
26
|
+
LEGACY_CONFIG_VOLUME = "kamal-proxy-config"
|
|
27
|
+
LEGACY_LOADBALANCER_CONFIG_VOLUME = "kamal-loadbalancer-config"
|
|
28
|
+
LEGACY_IMAGE_TITLE = "kamal-proxy"
|
|
29
|
+
LEGACY_LOADBALANCER_IMAGE_TITLE = "kamal-loadbalancer"
|
|
30
|
+
|
|
31
|
+
# What `compress: true` offers. dash-proxy has no "on" state without an
|
|
10
32
|
# explicit list - --compress *is* the list - so the shorthand has to pick.
|
|
11
33
|
# Best ratio first, matching the proxy's own default ordering; the client's
|
|
12
34
|
# Accept-Encoding q-values still outrank this preference.
|
|
@@ -14,7 +36,7 @@ class Kamal::Configuration::Proxy
|
|
|
14
36
|
|
|
15
37
|
SUPPORTED_COMPRESSION_ENCODINGS = %w[ gzip br zstd ].freeze
|
|
16
38
|
|
|
17
|
-
#
|
|
39
|
+
# dash-proxy maps `brotli` onto the `br` token that travels in Content-Encoding.
|
|
18
40
|
COMPRESSION_ENCODING_ALIASES = { "brotli" => "br" }.freeze
|
|
19
41
|
|
|
20
42
|
# The layering contract. When the fork's load balancer fronts the per-host
|
|
@@ -32,7 +54,7 @@ class Kamal::Configuration::Proxy
|
|
|
32
54
|
# Without load balancing the single proxy is every layer at once and the
|
|
33
55
|
# whole surface applies to it.
|
|
34
56
|
DEPLOY_OPTION_DISPOSITIONS = {
|
|
35
|
-
# --- Edge: TLS terminates where the handshake happens, and
|
|
57
|
+
# --- Edge: TLS terminates where the handshake happens, and dash-proxy
|
|
36
58
|
# gates TLSRedirect on TLSEnabled, so the whole family travels together.
|
|
37
59
|
host: :edge,
|
|
38
60
|
tls: :edge,
|
|
@@ -59,7 +81,7 @@ class Kamal::Configuration::Proxy
|
|
|
59
81
|
"rate-limit-burst": :edge,
|
|
60
82
|
"rate-limit-exempt": :edge,
|
|
61
83
|
|
|
62
|
-
# --- Edge:
|
|
84
|
+
# --- Edge: dash-proxy deletes the Authorization header once a service
|
|
63
85
|
# enforces basic auth, so an inner proxy would 401 the credential-less
|
|
64
86
|
# request the load balancer forwards. Credentials belong at the edge only.
|
|
65
87
|
"basic-auth": :edge,
|
|
@@ -163,12 +185,12 @@ class Kamal::Configuration::Proxy
|
|
|
163
185
|
# where it matters.
|
|
164
186
|
def self.disposition(key)
|
|
165
187
|
DEPLOY_OPTION_DISPOSITIONS.fetch(key) do
|
|
166
|
-
raise
|
|
167
|
-
"proxy deploy option --#{key} has no layering disposition - add it to
|
|
188
|
+
raise Dash::ConfigurationError,
|
|
189
|
+
"proxy deploy option --#{key} has no layering disposition - add it to Dash::Configuration::Proxy::DEPLOY_OPTION_DISPOSITIONS"
|
|
168
190
|
end
|
|
169
191
|
end
|
|
170
192
|
|
|
171
|
-
delegate :argumentize, :optionize, :seconds_duration, to:
|
|
193
|
+
delegate :argumentize, :optionize, :seconds_duration, to: Dash::Utils
|
|
172
194
|
|
|
173
195
|
attr_reader :config, :proxy_config, :role_name, :run, :secrets
|
|
174
196
|
|
|
@@ -182,8 +204,8 @@ class Kamal::Configuration::Proxy
|
|
|
182
204
|
@role_name = role_name
|
|
183
205
|
@load_balanced = load_balanced
|
|
184
206
|
@secrets = secrets
|
|
185
|
-
validate! @proxy_config, with:
|
|
186
|
-
@run =
|
|
207
|
+
validate! @proxy_config, with: Dash::Configuration::Validator::Proxy, context: context
|
|
208
|
+
@run = Dash::Configuration::Proxy::Run.new(config, run_config: @proxy_config["run"], context: "#{context}/run") if @proxy_config && @proxy_config["run"].present?
|
|
187
209
|
end
|
|
188
210
|
|
|
189
211
|
def app_port
|
|
@@ -274,7 +296,7 @@ class Kamal::Configuration::Proxy
|
|
|
274
296
|
ssl_config["on_demand_url"]
|
|
275
297
|
end
|
|
276
298
|
|
|
277
|
-
# The name of a secret in .
|
|
299
|
+
# The name of a secret in .dash/secrets holding the CA bundle client
|
|
278
300
|
# certificates must chain to - mirroring ssl.certificate_pem, not a local
|
|
279
301
|
# file path. Kamal uploads the content into the app's TLS directory, which
|
|
280
302
|
# the proxy container already mounts, and hands the proxy the path it sees
|
|
@@ -294,7 +316,7 @@ class Kamal::Configuration::Proxy
|
|
|
294
316
|
def client_ca_pem_content
|
|
295
317
|
secrets[client_ca_pem].tap do |content|
|
|
296
318
|
if content.blank?
|
|
297
|
-
raise
|
|
319
|
+
raise Dash::ConfigurationError, "proxy/ssl: client_ca_pem secret '#{client_ca_pem}' is empty"
|
|
298
320
|
end
|
|
299
321
|
end
|
|
300
322
|
end
|
|
@@ -311,7 +333,7 @@ class Kamal::Configuration::Proxy
|
|
|
311
333
|
proxy_config["path_prefixes"] || proxy_config["path_prefix"]&.split(",") || []
|
|
312
334
|
end
|
|
313
335
|
|
|
314
|
-
# Nil when unset: the default lives in
|
|
336
|
+
# Nil when unset: the default lives in dash-proxy, not here.
|
|
315
337
|
def healthcheck_path
|
|
316
338
|
proxy_config.dig("healthcheck", "path")
|
|
317
339
|
end
|
|
@@ -370,7 +392,7 @@ class Kamal::Configuration::Proxy
|
|
|
370
392
|
optionize ({ target: "#{target}:#{app_port}" }).merge(deploy_options), with: "="
|
|
371
393
|
end
|
|
372
394
|
|
|
373
|
-
#
|
|
395
|
+
# dash-proxy rollout deploy only accepts the target and the timeouts - the service already
|
|
374
396
|
# exists, so it keeps the host, TLS, buffering and logging options of the live deploy.
|
|
375
397
|
def rollout_deploy_options
|
|
376
398
|
{
|
|
@@ -405,7 +427,7 @@ class Kamal::Configuration::Proxy
|
|
|
405
427
|
private
|
|
406
428
|
# Which dispositions this layer keeps. The per-app proxy behind a load
|
|
407
429
|
# balancer sheds the edge concerns; without load balancing there is no
|
|
408
|
-
# other layer to defer to.
|
|
430
|
+
# other layer to defer to. Dash::Configuration::Loadbalancer overrides
|
|
409
431
|
# this to keep the edge and shed the per-app concerns.
|
|
410
432
|
def retained_dispositions
|
|
411
433
|
load_balancing? ? %i[ per_app both ] : %i[ edge per_app both ]
|
|
@@ -417,7 +439,7 @@ class Kamal::Configuration::Proxy
|
|
|
417
439
|
|
|
418
440
|
# Auto-activation needs a role the load balancer can actually front. The
|
|
419
441
|
# target list is built from roles where `running_proxy?` (see
|
|
420
|
-
#
|
|
442
|
+
# Dash::Cli::Proxy#loadbalancer), so a proxy-less primary role would boot a
|
|
421
443
|
# load balancer with an empty --target. An explicit `loadbalancer:` setting
|
|
422
444
|
# skips this check — the operator asked for it.
|
|
423
445
|
def auto_load_balanced_primary_role?
|
|
@@ -426,7 +448,7 @@ class Kamal::Configuration::Proxy
|
|
|
426
448
|
primary_role.present? && primary_role.running_proxy? && Array(primary_role.hosts).size > 1
|
|
427
449
|
end
|
|
428
450
|
|
|
429
|
-
# Flags for
|
|
451
|
+
# Flags for dash-proxy's dynamic domain source (runtime TLS hostnames).
|
|
430
452
|
# TLS terminates wherever these flags land — :edge in the layering contract.
|
|
431
453
|
def ssl_domains_options
|
|
432
454
|
{
|
|
@@ -449,7 +471,7 @@ class Kamal::Configuration::Proxy
|
|
|
449
471
|
# The connection pool between the proxy and this app's containers, and how
|
|
450
472
|
# hard the proxy tries to place a request on a healthy one.
|
|
451
473
|
#
|
|
452
|
-
# Every value is passed through exactly as written.
|
|
474
|
+
# Every value is passed through exactly as written. dash-proxy resolves its
|
|
453
475
|
# own defaults from a zero (target_pool.go), and it has to do that server
|
|
454
476
|
# side because restored state and older RPC clients never see the CLI — so
|
|
455
477
|
# substituting a default here would be both redundant and wrong.
|
|
@@ -473,7 +495,7 @@ class Kamal::Configuration::Proxy
|
|
|
473
495
|
# app hosts have the docker socket and the containers).
|
|
474
496
|
#
|
|
475
497
|
# Sleep needs the container runtime socket, which is a run-level setting -
|
|
476
|
-
#
|
|
498
|
+
# Dash::Configuration#ensure_sleep_has_a_docker_socket refuses the pairing
|
|
477
499
|
# rather than letting the first request after an idle period hang.
|
|
478
500
|
def lifecycle_options
|
|
479
501
|
affinity = proxy_config["session_affinity"] || {}
|
|
@@ -517,7 +539,7 @@ class Kamal::Configuration::Proxy
|
|
|
517
539
|
proxy_config["headers"] || {}
|
|
518
540
|
end
|
|
519
541
|
|
|
520
|
-
#
|
|
542
|
+
# dash-proxy cuts a rule at the first colon, so a value carrying colons of
|
|
521
543
|
# its own arrives intact.
|
|
522
544
|
def header_rules(direction, verb)
|
|
523
545
|
(headers_config.dig(direction, verb) || {}).map { |name, value| "#{name}: #{value}" }.presence
|
|
@@ -574,7 +596,7 @@ class Kamal::Configuration::Proxy
|
|
|
574
596
|
|
|
575
597
|
# The cache policy, which is per service - the store it writes into is
|
|
576
598
|
# proxy-wide and lives in proxy/run/cache. Only --cache is derived from a
|
|
577
|
-
# truthy key; every other default stays in
|
|
599
|
+
# truthy key; every other default stays in dash-proxy, so an unset key emits
|
|
578
600
|
# nothing rather than restating a default the gem would then have to track.
|
|
579
601
|
def cache_options
|
|
580
602
|
cache = proxy_config["cache"] || {}
|
|
@@ -600,9 +622,9 @@ class Kamal::Configuration::Proxy
|
|
|
600
622
|
File.join([ directory, role_name, filename ].compact)
|
|
601
623
|
end
|
|
602
624
|
|
|
603
|
-
#
|
|
625
|
+
# dash-proxy takes the credential as <username>:<password> and cuts at the
|
|
604
626
|
# first colon, so a password may contain colons but a username may not (the
|
|
605
|
-
# validator enforces that). The password is read from .
|
|
627
|
+
# validator enforces that). The password is read from .dash/secrets when
|
|
606
628
|
# password_secret names it, so it need not live in deploy.yml.
|
|
607
629
|
def basic_auth_credential
|
|
608
630
|
basic_auth = proxy_config["basic_auth"]
|
|
@@ -619,16 +641,16 @@ class Kamal::Configuration::Proxy
|
|
|
619
641
|
# means the named secret resolved empty. Fail rather than drop the flag —
|
|
620
642
|
# silently deploying an unprotected service is the worse outcome.
|
|
621
643
|
if password.blank?
|
|
622
|
-
raise
|
|
644
|
+
raise Dash::ConfigurationError, "proxy/basic_auth: password_secret '#{secret_name}' is empty"
|
|
623
645
|
end
|
|
624
646
|
|
|
625
647
|
# Sensitive, so SSHKit redacts the credential wherever kamal prints the
|
|
626
648
|
# deploy command - at :info verbosity it used to land in plain text
|
|
627
649
|
# (registry-login precedent; Utils.optionize passes the marking through).
|
|
628
|
-
|
|
650
|
+
Dash::Utils.sensitive("#{basic_auth["username"]}:#{password}")
|
|
629
651
|
end
|
|
630
652
|
|
|
631
|
-
# Serves both --path-timeout and --path-request-timeout, which
|
|
653
|
+
# Serves both --path-timeout and --path-request-timeout, which dash-proxy
|
|
632
654
|
# reads with one parser. A duration may be a Go string ("5m") or plain
|
|
633
655
|
# seconds; 0 is a value, meaning no limit for that prefix.
|
|
634
656
|
def path_timeout_args(key)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
class
|
|
2
|
-
include
|
|
1
|
+
class Dash::Configuration::Registry
|
|
2
|
+
include Dash::Configuration::Validation
|
|
3
3
|
|
|
4
4
|
def initialize(config:, secrets:, context: "registry")
|
|
5
5
|
@registry_config = config["registry"] || {}
|
|
6
6
|
@secrets = secrets
|
|
7
|
-
validate! registry_config, context: context, with:
|
|
7
|
+
validate! registry_config, context: context, with: Dash::Configuration::Validator::Registry
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def server
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Role::Healthcheck
|
|
2
2
|
DEFAULT_PATH = "/up"
|
|
3
3
|
DEFAULT_INTERVAL = 1
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ class Kamal::Configuration::Role::Healthcheck
|
|
|
7
7
|
DOCKER_ONLY_KEYS = %w[ cmd port path interval timeout retries start_period start_interval ]
|
|
8
8
|
|
|
9
9
|
attr_reader :healthcheck_config, :context
|
|
10
|
-
delegate :optionize, to:
|
|
10
|
+
delegate :optionize, to: Dash::Utils
|
|
11
11
|
|
|
12
12
|
def initialize(healthcheck_config:, context: "healthcheck")
|
|
13
13
|
@healthcheck_config = healthcheck_config
|
|
@@ -90,6 +90,6 @@ class Kamal::Configuration::Role::Healthcheck
|
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
def error(message, context: nil)
|
|
93
|
-
raise
|
|
93
|
+
raise Dash::ConfigurationError, "#{[ @context, context ].compact.join("/")}: #{message}"
|
|
94
94
|
end
|
|
95
95
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
class
|
|
2
|
-
include
|
|
1
|
+
class Dash::Configuration::Role
|
|
2
|
+
include Dash::Configuration::Validation
|
|
3
3
|
|
|
4
|
-
delegate :argumentize, :optionize, to:
|
|
4
|
+
delegate :argumentize, :optionize, to: Dash::Utils
|
|
5
5
|
|
|
6
6
|
attr_reader :name, :config, :specialized_env, :specialized_logging, :specialized_proxy, :healthcheck
|
|
7
7
|
|
|
@@ -13,20 +13,20 @@ class Kamal::Configuration::Role
|
|
|
13
13
|
role_config,
|
|
14
14
|
example: validation_yml["servers"]["workers"],
|
|
15
15
|
context: "servers/#{name}",
|
|
16
|
-
with:
|
|
16
|
+
with: Dash::Configuration::Validator::Role
|
|
17
17
|
|
|
18
|
-
@specialized_env =
|
|
18
|
+
@specialized_env = Dash::Configuration::Env.new \
|
|
19
19
|
config: specializations.fetch("env", {}),
|
|
20
20
|
secrets: config.secrets,
|
|
21
21
|
context: "servers/#{name}/env"
|
|
22
22
|
|
|
23
|
-
@specialized_logging =
|
|
23
|
+
@specialized_logging = Dash::Configuration::Logging.new \
|
|
24
24
|
logging_config: specializations.fetch("logging", {}),
|
|
25
25
|
context: "servers/#{name}/logging"
|
|
26
26
|
|
|
27
27
|
# `healthcheck: false` is an opt-out, not a healthcheck — it leaves @healthcheck nil.
|
|
28
28
|
if healthcheck_config = specializations["healthcheck"]
|
|
29
|
-
@healthcheck =
|
|
29
|
+
@healthcheck = Dash::Configuration::Role::Healthcheck.new \
|
|
30
30
|
healthcheck_config: healthcheck_config,
|
|
31
31
|
context: "servers/#{name}/healthcheck"
|
|
32
32
|
end
|
|
@@ -94,13 +94,13 @@ class Kamal::Configuration::Role
|
|
|
94
94
|
# `boot.wait` a second time inside every group.
|
|
95
95
|
#
|
|
96
96
|
# Built on first read rather than in the initializer — Servers.new constructs every Role
|
|
97
|
-
# before
|
|
97
|
+
# before Dash::Configuration#initialize has finished assigning its own collaborators.
|
|
98
98
|
def boot
|
|
99
99
|
return @boot if defined?(@boot)
|
|
100
100
|
|
|
101
101
|
@boot =
|
|
102
102
|
if (boot_config = specializations["boot"])
|
|
103
|
-
|
|
103
|
+
Dash::Configuration::Boot.new \
|
|
104
104
|
config: config, boot_config: boot_config, context: "servers/#{name}/boot"
|
|
105
105
|
end
|
|
106
106
|
end
|
|
@@ -148,7 +148,7 @@ class Kamal::Configuration::Role
|
|
|
148
148
|
def readiness_description
|
|
149
149
|
case readiness_source
|
|
150
150
|
when :proxy
|
|
151
|
-
[ "
|
|
151
|
+
[ "dash-proxy health check", proxy.healthcheck_path ].compact.join(" ")
|
|
152
152
|
when :healthcheck
|
|
153
153
|
healthcheck.port ? "healthcheck #{healthcheck.path}:#{healthcheck.port}" : "healthcheck (custom cmd)"
|
|
154
154
|
when :healthcheck_exec
|
|
@@ -168,7 +168,7 @@ class Kamal::Configuration::Role
|
|
|
168
168
|
end
|
|
169
169
|
|
|
170
170
|
def stop_args
|
|
171
|
-
# When deploying with the proxy,
|
|
171
|
+
# When deploying with the proxy, dash-proxy will drain request before returning so we don't need to wait.
|
|
172
172
|
timeout = stop_timeout || (running_proxy? ? nil : config.drain_timeout)
|
|
173
173
|
|
|
174
174
|
[ *argumentize("-t", timeout) ]
|
|
@@ -235,7 +235,7 @@ class Kamal::Configuration::Role
|
|
|
235
235
|
|
|
236
236
|
def asset_volume(version = config.version)
|
|
237
237
|
if assets?
|
|
238
|
-
|
|
238
|
+
Dash::Configuration::Volume.new \
|
|
239
239
|
host_path: asset_volume_directory(version), container_path: asset_path, options: asset_path_options
|
|
240
240
|
end
|
|
241
241
|
end
|
|
@@ -255,7 +255,7 @@ class Kamal::Configuration::Role
|
|
|
255
255
|
def ensure_one_host_for_ssl
|
|
256
256
|
# Skip SSL validation when a loadbalancer is present or custom certificates are provided
|
|
257
257
|
if running_proxy? && proxy.ssl? && hosts.size > 1 && !proxy.loadbalancer.present? && !proxy.custom_ssl_certificate?
|
|
258
|
-
raise
|
|
258
|
+
raise Dash::ConfigurationError, "SSL is only supported on a single server unless you provide custom certificates or configure a loadbalancer, found #{hosts.size} servers for role #{name}"
|
|
259
259
|
end
|
|
260
260
|
end
|
|
261
261
|
|
|
@@ -274,7 +274,7 @@ class Kamal::Configuration::Role
|
|
|
274
274
|
if running_proxy?
|
|
275
275
|
proxy_config = proxy_specializations == true || proxy_specializations.nil? ? {} : proxy_specializations
|
|
276
276
|
|
|
277
|
-
@specialized_proxy =
|
|
277
|
+
@specialized_proxy = Dash::Configuration::Proxy.new \
|
|
278
278
|
config: config,
|
|
279
279
|
proxy_config: proxy_config,
|
|
280
280
|
secrets: config.secrets,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
class
|
|
2
|
-
include
|
|
1
|
+
class Dash::Configuration::Servers
|
|
2
|
+
include Dash::Configuration::Validation
|
|
3
3
|
|
|
4
4
|
attr_reader :config, :servers_config, :roles
|
|
5
5
|
|
|
6
6
|
def initialize(config:)
|
|
7
7
|
@config = config
|
|
8
8
|
@servers_config = config.raw_config.servers
|
|
9
|
-
validate! servers_config, with:
|
|
9
|
+
validate! servers_config, with: Dash::Configuration::Validator::Servers
|
|
10
10
|
|
|
11
|
-
@roles = role_names.map { |role_name|
|
|
11
|
+
@roles = role_names.map { |role_name| Dash::Configuration::Role.new role_name, config: config }
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
private
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require "yaml"
|
|
2
2
|
require "active_support/inflector"
|
|
3
3
|
|
|
4
|
-
module
|
|
4
|
+
module Dash::Configuration::Validation
|
|
5
5
|
extend ActiveSupport::Concern
|
|
6
6
|
|
|
7
7
|
class_methods do
|
|
@@ -14,7 +14,7 @@ module Kamal::Configuration::Validation
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def validate!(config, example: nil, context: nil, with:
|
|
17
|
+
def validate!(config, example: nil, context: nil, with: Dash::Configuration::Validator)
|
|
18
18
|
context ||= self.class.validation_config_key
|
|
19
19
|
example ||= validation_yml[self.class.validation_config_key]
|
|
20
20
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Validator::Alias < Dash::Configuration::Validator
|
|
2
2
|
def validate!
|
|
3
3
|
super
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ class Kamal::Configuration::Validator::Alias < Kamal::Configuration::Validator
|
|
|
8
8
|
error "Invalid alias name: '#{name}'. Must only contain lowercase letters, alphanumeric, hyphens and underscores."
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
if
|
|
11
|
+
if Dash::Cli::Main.commands.include?(name)
|
|
12
12
|
error "Alias '#{name}' conflicts with a built-in command."
|
|
13
13
|
end
|
|
14
14
|
end
|